package main
import (
+ "github.com/sirupsen/logrus"
"k8shelm/pkg/plugin"
- "log"
"os"
)
+const (
+ serverPort = 50051
+ certificate = ""
+ key = ""
+ logFile = "/go/release/logfile"
+ loggerLevel = logrus.InfoLevel
+)
+
func main() {
- logger := log.New(os.Stdout, "helm ", log.LstdFlags|log.Lshortfile)
- serverConfig := plugin.ServerGRPCConfig{Certificate:"", Port:50051, Key:""}
- server, err := plugin.NewServerGRPC(serverConfig)
+ // Prepare logger
+ file, err := os.Create(logFile)
if err != nil {
- logger.Fatalf("failed to create server: %v", err)
+ logrus.Fatal(err)
}
- error := server.Listen()
- if error != nil {
+ defer file.Close()
+
+ var logger = plugin.GetLogger(logFile, loggerLevel, file)
+
+ // Create GRPC server
+ serverConfig := plugin.ServerGRPCConfig{Certificate: certificate, Port:serverPort, Key:key, Logger:logger}
+ server := plugin.NewServerGRPC(serverConfig)
+
+ // Start listening
+ err = server.Listen()
+ if err != nil {
logger.Fatalf("failed to listen: %v", err)
}
}
module k8shelm
-go 1.13
+go 1.14
require (
github.com/golang/protobuf v1.4.1
- github.com/googleapis/gnostic v0.3.1 // indirect
- github.com/onsi/gomega v1.8.1 // indirect
- golang.org/x/net v0.0.0-20200505041828-1ed23360d12c // indirect
- google.golang.org/grpc v1.28.1
+ github.com/sirupsen/logrus v1.4.2
+ google.golang.org/grpc v1.29.1
google.golang.org/protobuf v1.22.0
- gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
helm.sh/helm/v3 v3.2.0
rsc.io/letsencrypt v0.0.3 // indirect
)
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
-github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI=
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
-github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 h1:893HsJqtxp9z1SF76gg6hY70hRY1wVlTSnC/h1yUDCo=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
-github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
-github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200505041828-1ed23360d12c h1:zJ0mtu4jCalhKg6Oaukv6iIkb+cOvDrajDH9DH46Q4M=
-golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.28.1 h1:C1QC6KzgSiLyBabDi87BbjaGreoRgGUF5nOyvfrAZ1k=
-google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
+google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
+google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+/*
+ * Copyright 2020 Huawei Technologies Co., Ltd.
+ *
+ * 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.
+ */
package plugin
import (
"bytes"
"context"
- "k8shelm/internal/lcmservice"
+ "github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
_ "google.golang.org/grpc/encoding/gzip"
"google.golang.org/grpc/status"
"io"
- "log"
+ "k8shelm/internal/lcmservice"
"net"
"os"
"strconv"
)
+// GRPC server
type ServerGRPC struct {
server *grpc.Server
port int
certificate string
key string
+ logger *logrus.Logger
}
+// GRPC service configuration used to create GRPC server
type ServerGRPCConfig struct {
Certificate string
Key string
Port int
+ Logger *logrus.Logger
}
-func NewServerGRPC(cfg ServerGRPCConfig) (s ServerGRPC, err error) {
- logger := log.New(os.Stdout, "helmplugin ", log.LstdFlags|log.Lshortfile)
- if cfg.Port == 0 {
- logger.Fatalf("Port must be specified")
- }
+// Constructor to GRPC server
+func NewServerGRPC(cfg ServerGRPCConfig) (s ServerGRPC) {
+ s.logger = cfg.Logger
s.port = cfg.Port
s.certificate = cfg.Certificate
s.key = cfg.Key
- logger.Println("Binding is successful")
+ s.logger.Infof("Binding is successful")
return
}
+// Start GRPC server and start listening on the port
func (s *ServerGRPC) Listen() (err error) {
- logger := log.New(os.Stdout, "helmplugin ", log.LstdFlags|log.Lshortfile)
var (
listener net.Listener
grpcOpts = []grpc.ServerOption{}
grpcCreds credentials.TransportCredentials
)
- logger.Println("Listening start")
-
+ // Listen announces on the network address
listener, err = net.Listen("tcp", ":"+strconv.Itoa(s.port))
-
- logger.Println("Listening end")
-
if err != nil {
- logger.Fatalf("failed to listen on port: ", s.port)
+ s.logger.Fatalf("failed to listen on port: %s. Err: %s", s.port, err)
+ return err
}
+ s.logger.Infof("Server started listening on port ", s.port)
+ // Secure connection if asked
if s.certificate != "" && s.key != "" {
grpcCreds, err = credentials.NewServerTLSFromFile(
s.certificate, s.key)
if err != nil {
- logger.Fatalf("failed to create tls grpc server using cert %s and key: ", s.certificate, s.key)
+ s.logger.Fatalf("failed to create tls grpc server using cert %s and key: %s. Err: %s", s.certificate, s.key, err)
}
-
grpcOpts = append(grpcOpts, grpc.Creds(grpcCreds))
}
- logger.Println("New server creation")
-
+ // Register server with GRPC
s.server = grpc.NewServer(grpcOpts...)
-
- logger.Println("New server creation success")
-
lcmservice.RegisterAppLCMServer(s.server, s)
- logger.Println("New server registration success")
-
+ s.logger.Infof("Server registered with GRPC")
+ // Server start serving
err = s.server.Serve(listener)
if err != nil {
- logger.Fatalf("errored listening for grpc connections")
+ s.logger.Fatalf("failed to listen for grpc connections. Err: %s", err)
+ return err
}
-
- logger.Println("Server is serving")
-
-
return
}
+// Query HELM chart
func (s *ServerGRPC) Query(ctx context.Context, req *lcmservice.QueryRequest) (resp *lcmservice.QueryResponse, err error) {
- r := queryChart(req.GetWorkloadId(), req.GetHostIp())
+
+ // Input validation
+ if (req.GetHostIp() == "") || (req.GetWorkloadId() == "") {
+ return nil, s.logError(status.Errorf(codes.InvalidArgument, "Nil input HostIp: %s or workloadId: %s. " +
+ "Err: %s", req.GetHostIp(), req.GetWorkloadId(), err))
+ }
+
+ // Create HELM Client
+ hc, err := NewHelmClient(req.GetHostIp(), s.logger)
+ if os.IsNotExist(err) {
+ return nil, s.logError(status.Errorf(codes.InvalidArgument, "Kubeconfig for HostIp can't be found: %s. " +
+ "Err: %s", req.GetHostIp(), err))
+ }
+
+ // Query Chart
+ r, err := hc.queryChart(req.GetWorkloadId())
+ if (err != nil) {
+ return nil, s.logError(status.Errorf(codes.NotFound, "Chart not found for workloadId: %s. Err: %s",
+ req.GetWorkloadId(), err))
+ }
resp = &lcmservice.QueryResponse{
Status: r,
}
return resp, nil
}
+// Terminate HELM charts
func (s *ServerGRPC) Terminate(ctx context.Context, req *lcmservice.TerminateRequest) (resp *lcmservice.TerminateResponse, err error) {
- logger := log.New(os.Stdout, "helmplugin ", log.LstdFlags|log.Lshortfile)
- uninstallChart(req.GetWorkloadId(), req.GetHostIp())
- resp = &lcmservice.TerminateResponse{
- Status: "Success",
+ // Input validation
+ if (req.GetHostIp() == "") || (req.GetWorkloadId() == "") {
+ return nil, s.logError(status.Errorf(codes.InvalidArgument, "Nil input HostIp: %s or workloadId: %s. " +
+ "Err: %s", req.GetHostIp(), req.GetWorkloadId(), err))
+ }
+
+ // Create HELM client
+ hc, err := NewHelmClient(req.GetHostIp(), s.logger)
+ if os.IsNotExist(err) {
+ return nil, s.logError(status.Errorf(codes.InvalidArgument, "Kubeconfig for HostIp can't be found: %s. " +
+ "Err: %s", req.GetHostIp(), err))
+ }
+
+ // Uninstall chart
+ err = hc.uninstallChart(req.GetWorkloadId())
+
+ if (err != nil) {
+ resp = &lcmservice.TerminateResponse{
+ Status: "Failure",
+ }
+ return resp, s.logError(status.Errorf(codes.NotFound, "Chart not found for workloadId: %s. Err: %s",
+ req.GetWorkloadId(), err))
+ } else {
+ resp = &lcmservice.TerminateResponse{
+ Status: "Success",
+ }
+ return resp, nil
}
- logger.Printf("Termination completed")
- return resp, nil
}
+// Instantiate HELM Chart
func (s *ServerGRPC) Instantiate(stream lcmservice.AppLCM_InstantiateServer) (err error) {
- logger := log.New(os.Stdout, "helmplugin ", log.LstdFlags|log.Lshortfile)
+ // Recieve metadata which is host ip
req, err := stream.Recv()
if err != nil {
- logger.Fatalf("cannot receive package metadata")
+ s.logger.Errorf("Cannot receive package metadata. Err: %s", err)
+ return
}
hostIP := req.GetHostIp()
- logger.Printf("receive an upload-image request for package ip %s", hostIP)
+ s.logger.Info("Recieved instantiate request for host ", hostIP)
- helmPkg := bytes.Buffer{}
+ // Host validation
+ if (hostIP == "") {
+ return s.logError(status.Errorf(codes.InvalidArgument, "Nil input for HostIp: %s Err: %s", req.GetHostIp(), err))
+ }
+ // Receive package
+ helmPkg := bytes.Buffer{}
for {
- err := contextError(stream.Context())
+ err := s.contextError(stream.Context())
if err != nil {
return err
}
- logger.Printf("waiting to receive more data")
+ s.logger.Info("Waiting to receive more data")
req, err := stream.Recv()
if err == io.EOF {
- logger.Printf("no more data")
+ s.logger.Info("No more data")
break
}
if err != nil {
- return logError(status.Errorf(codes.Unknown, "cannot receive chunk data: %v", err))
+ return s.logError(status.Errorf(codes.Unknown, "cannot receive chunk data: %v", err))
}
+ // Receive chunk and write to helm package
chunk := req.GetPackage()
- logger.Printf("received a chunk ")
+ s.logger.Info("Recieved chunk")
- // write slowly
- // time.Sleep(time.Second)
_, err = helmPkg.Write(chunk)
if err != nil {
- return logError(status.Errorf(codes.Internal, "cannot write chunk data: %v", err))
+ return s.logError(status.Errorf(codes.Internal, "cannot write chunk data: %v", err))
}
}
- relName := installChart(helmPkg, hostIP)
-
- res := &lcmservice.InstantiateResponse{
- WorkloadId: relName,
- Status: "Success",
+ // Create HELM client
+ hc, err := NewHelmClient(req.GetHostIp(), s.logger)
+ if os.IsNotExist(err) {
+ return s.logError(status.Errorf(codes.InvalidArgument, "Kubeconfig for HostIp can't be found: %s. " +
+ "Err: %s", req.GetHostIp(), err))
}
- err = stream.SendAndClose(res)
- if err != nil {
- return logError(status.Errorf(codes.Unknown, "cannot send response: %v", err))
- }
+ relName, err := hc.installChart(helmPkg)
- logger.Printf("Instantation completed")
- return
-}
+ var res lcmservice.InstantiateResponse
+ res.WorkloadId = relName
+ if (err != nil) {
+ res.Status = "Failure"
+ } else {
+ res.Status = "Success"
+ }
-func (s *ServerGRPC) Close() {
- if s.server != nil {
- s.server.Stop()
+ err = stream.SendAndClose(&res)
+ if err != nil {
+ return s.logError(status.Errorf(codes.Unknown, "cannot send response: %v", err))
}
+ s.logger.Info("Successful Instantiation")
return
}
-func contextError(ctx context.Context) error {
+func (s *ServerGRPC) contextError(ctx context.Context) error {
switch ctx.Err() {
case context.Canceled:
- return logError(status.Error(codes.Canceled, "request is canceled"))
+ return s.logError(status.Error(codes.Canceled, "request is canceled"))
case context.DeadlineExceeded:
- return logError(status.Error(codes.DeadlineExceeded, "deadline is exceeded"))
+ return s.logError(status.Error(codes.DeadlineExceeded, "deadline is exceeded"))
default:
return nil
}
}
-func logError(err error) error {
+func (s *ServerGRPC) logError(err error) error {
if err != nil {
- log.Print(err)
+ s.logger.Errorf("Error Information: ", err)
}
return err
}
\ No newline at end of file
+/*
+ * Copyright 2020 Huawei Technologies Co., Ltd.
+ *
+ * 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.
+ */
package plugin
import (
"bytes"
"fmt"
+ "github.com/sirupsen/logrus"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/kube"
- "log"
"os"
)
-const releaseNamespace = "default"
-const chartPath = "/go/release/charts/"
-const kubeconfigPath = "/go/release/kubeconfig/"
+// Constants to be taken from deployment file
+const (
+ releaseNamespace = "default"
+ chartPath = "/go/release/charts/"
+ kubeconfigPath = "/go/release/kubeconfig/"
+)
+
+// Helm client
+type HelmClient struct {
+ hostIP string
+ kubeconfig string
+ logger *logrus.Logger
+}
-//const chartPath = "/home/root1/code/mecm/mepm/applcm/k8shelm/pkg/plugin/"
-//const kubeconfigPath = "/home/root1/"
+// Constructor of helm client for a given host IP
+func NewHelmClient(hostIP string, logger *logrus.Logger) (*HelmClient, error) {
+ // Kubeconfig file will be picked based on host IP and will be check for existence
+ exists, err := fileExists(kubeconfigPath + hostIP)
+ if exists {
+ return &HelmClient{hostIP: hostIP, kubeconfig: kubeconfigPath + hostIP, logger: logger}, nil
+ } else {
+ logger.Errorf("No file exist with name: %s. Err: %s", kubeconfigPath + hostIP)
+ return nil, err
+ }
+}
-func installChart(helmPkg bytes.Buffer, hostIP string) string {
- logger := log.New(os.Stdout, "helmplugin ", log.LstdFlags|log.Lshortfile)
- logger.Println("Inside helm client")
+// Install a given helm chart
+func (hc *HelmClient) installChart(helmPkg bytes.Buffer) (string, error) {
+ hc.logger.Info("Inside helm client")
+ // Create temporary file to hold helm chart
file, err := os.Create(chartPath + "temp.tar.gz")
if err != nil {
- logger.Printf("unable to create file")
+ hc.logger.Errorf("Unable to create file: %s. Err: %s", chartPath + "temp.tar.gz", err)
+ return "", err
}
+ defer os.Remove(chartPath + "temp.tar.gz")
+ // Write input bytes to temp file
_, err = helmPkg.WriteTo(file)
if err != nil {
- logger.Printf("uanble to write to file")
+ hc.logger.Errorf("Unable to write to file: %s. Err: %s", chartPath + "temp.tar.gz", err)
+ return "", err
}
+ // Load the file to chart
chart, err := loader.Load(chartPath + "temp.tar.gz")
if err != nil {
-
- panic(err)
+ hc.logger.Errorf("Unable to load chart from file: %s. Err: %s", chartPath + "temp.tar.gz", err)
+ return "", err
}
- releaseName := chart.Metadata.Name
-
- kubeconfig := kubeconfigPath + hostIP
+ // Release name will be taken from the name in chart's metadata
+ relName := chart.Metadata.Name
+ // Initialize action config
actionConfig := new(action.Configuration)
- if err := actionConfig.Init(kube.GetConfig(kubeconfig, "", releaseNamespace), releaseNamespace, os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
+ if err := actionConfig.Init(kube.GetConfig(hc.kubeconfig, "", releaseNamespace), releaseNamespace,
+ os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
fmt.Sprintf(format, v)
- }); err != nil {
- panic(err)
- }
+ }); err != nil {
+ hc.logger.Errorf("Unable to initialize action config Err: %s", err)
+ return "", err
+ }
- iCli := action.NewInstall(actionConfig)
- iCli.Namespace = releaseNamespace
- iCli.ReleaseName = releaseName
- rel, err := iCli.Run(chart, nil)
+ // Prepare chart install action and install chart
+ installer := action.NewInstall(actionConfig)
+ installer.Namespace = releaseNamespace
+ installer.ReleaseName = relName
+ rel, err := installer.Run(chart, nil)
if err != nil {
- panic(err)
+ hc.logger.Errorf("Unable to install chart with release name: %s. Err: %s", relName, err)
+ return "", err
}
- fmt.Println("Successfully installed release: ", rel.Name)
- return rel.Name
+ hc.logger.Info("Successfully create chart with release name: %s", relName)
+ return rel.Name, err
}
-func uninstallChart(relName string, hostIP string) {
- kubeconfig := kubeconfigPath + hostIP
+// Un-Install a given helm chart
+func (hc *HelmClient) uninstallChart(relName string) (error) {
+ // Prepare action config and uninstall chart
actionConfig := new(action.Configuration)
- if err := actionConfig.Init(kube.GetConfig(kubeconfig, "", releaseNamespace), releaseNamespace, os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
+ if err := actionConfig.Init(kube.GetConfig(hc.kubeconfig, "", releaseNamespace), releaseNamespace,
+ os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
fmt.Sprintf(format, v)
- }); err != nil {
- panic(err)
- }
- iCli := action.NewUninstall(actionConfig)
- res, err := iCli.Run(relName);
+ }); err != nil {
+ hc.logger.Errorf("Unable to initialize action config Err: %s", err)
+ return err
+ }
+
+ ui := action.NewUninstall(actionConfig)
+ res, err := ui.Run(relName);
if err != nil {
- panic(err)
+ hc.logger.Errorf("Unable to uninstall chart with release name: %s. Err: %s", relName, err)
+ return err
}
- fmt.Println("Successfully uninstalled release: ", res.Info)
+ hc.logger.Info("Successfully uninstalled chart with release name: %s. Response Info: %s", res.Release.Name, res.Info)
+ return nil
}
-func queryChart(relName string, hostIP string) string {
- kubeconfig := kubeconfigPath + hostIP
+// Query a given chart
+func (hc *HelmClient) queryChart(relName string) (string, error) {
actionConfig := new(action.Configuration)
- if err := actionConfig.Init(kube.GetConfig(kubeconfig, "", releaseNamespace), releaseNamespace, os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
+ if err := actionConfig.Init(kube.GetConfig(hc.kubeconfig, "", releaseNamespace), releaseNamespace,
+ os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
fmt.Sprintf(format, v)
}); err != nil {
- panic(err)
+ hc.logger.Errorf("Unable to initialize action config Err: %s", err)
+ return "", err
}
- iCli := action.NewStatus(actionConfig)
- res, err := iCli.Run(relName)
+ s := action.NewStatus(actionConfig)
+ res, err := s.Run(relName)
if err != nil {
- panic(err)
+ hc.logger.Errorf("Unable to query chart with release name: %s. Err: %s", relName, err)
+ return "", err
+ }
+ return res.Info.Status.String(), nil
+}
+
+// fileExists checks if a file exists and is not a directory before we
+// try using it to prevent further errors.
+func fileExists(filename string) (bool, error) {
+ info, err := os.Stat(filename)
+ if os.IsNotExist(err) {
+ return false, err
}
- return res.Info.Status.String()
+ return !info.IsDir(), nil
}
--- /dev/null
+/*
+ * Copyright 2020 Huawei Technologies Co., Ltd.
+ *
+ * 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.
+ */
+package plugin
+
+import (
+ "github.com/sirupsen/logrus"
+ "os"
+)
+
+func GetLogger(logFile string, loggerLevel logrus.Level, file *os.File) *logrus.Logger {
+
+ logger := logrus.New()
+ logger.SetOutput(file)
+ logger.SetFormatter(&logrus.TextFormatter{
+ DisableColors: true,
+ FullTimestamp: true,
+ })
+ logger.SetLevel(loggerLevel)
+ logger.Info("logger created")
+ return logger
+}
\ No newline at end of file