diff --git a/docs/content/usage/crd-specs.md b/docs/content/usage/crd-specs.md index cb26ea7..6a52de4 100644 --- a/docs/content/usage/crd-specs.md +++ b/docs/content/usage/crd-specs.md @@ -194,6 +194,8 @@ FIELDS: secretSpec Specification to use for creating the Kubernetes Secret + + status ``` ### DockhandSecret.secretSpec diff --git a/go.mod b/go.mod index 8395cb9..b3814cd 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,13 @@ module github.com/boxboat/dockhand-secrets-operator go 1.16 require ( - github.com/boxboat/dockcmd v1.6.0 + github.com/boxboat/dockcmd v1.7.1 github.com/gobuffalo/packr/v2 v2.7.1 github.com/mitchellh/go-homedir v1.1.0 - github.com/rancher/lasso v0.0.0-20210408231703-9ddd9378d08d - github.com/rancher/wrangler v0.8.0 + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 + github.com/rancher/wrangler v0.8.5 github.com/sirupsen/logrus v1.7.0 - github.com/spf13/cobra v1.1.1 + github.com/spf13/cobra v1.1.3 github.com/spf13/viper v1.7.1 k8s.io/api v0.20.2 k8s.io/apimachinery v0.20.2 diff --git a/go.sum b/go.sum index 838091e..4566bc1 100644 --- a/go.sum +++ b/go.sum @@ -147,8 +147,8 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/boxboat/dockcmd v1.6.0 h1:PUP9HRqSA/lgHQ5fnjpoaeldyDWUTfkB9tNwxzTBBvk= -github.com/boxboat/dockcmd v1.6.0/go.mod h1:Wl2nsIyh56IubV0TNcB8tX4+NK4E9N5uF2FwLE91mPg= +github.com/boxboat/dockcmd v1.7.1 h1:GmAkN5x1gnLEfCocuvQcTyA9CKhaHuvwBhhOEgObT0I= +github.com/boxboat/dockcmd v1.7.1/go.mod h1:G3Gg9kkwD/41jQgjLezKI2vhUyqX3FLlK+AwWnFWTuI= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= @@ -487,7 +487,6 @@ github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVo github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= @@ -496,13 +495,11 @@ github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= -github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.6.2 h1:bHM2aVXwBtBJWxHtkSrWuI4umABCUczs52eiUS9nSiw= github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY= github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM= github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= @@ -521,7 +518,6 @@ github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -613,7 +609,6 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -644,7 +639,6 @@ github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUb github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -774,10 +768,10 @@ github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA= -github.com/rancher/lasso v0.0.0-20210408231703-9ddd9378d08d h1:vfjPEF6M7Jf1/zK1xF7z2drLfniooKcgDQdoXO5+U7w= -github.com/rancher/lasso v0.0.0-20210408231703-9ddd9378d08d/go.mod h1:OhBBBO1pBwYp0hacWdnvSGOj+XE9yMLOLnaypIlic18= -github.com/rancher/wrangler v0.8.0 h1:jGWr7ES0KwZU/8zB6lte0z4QB7hFcspaXPTvGmrvHok= -github.com/rancher/wrangler v0.8.0/go.mod h1:zSV5oh3+YZboilwcJmFHO3J6FZba82BTQft1b6ijx2I= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/wrangler v0.8.5 h1:aHUVvJrOhD6CGrAELWKDpo1MBDC8vKtEQZvjMPnw2cs= +github.com/rancher/wrangler v0.8.5/go.mod h1:dKEaHNB4izxmPUtpq1Hvr3z3Oh+9k5pCZyFO9sUhlaY= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -824,8 +818,8 @@ github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKv github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= -github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -936,7 +930,6 @@ golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -1167,6 +1160,7 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191017205301-920acffc3e65/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1363,8 +1357,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= @@ -1443,7 +1438,6 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/kube-aggregator v0.18.0 h1:J+wa9FDQ3SbgyA8wQBNg2m2FMSm+mMQfs2A58500hs0= k8s.io/kube-aggregator v0.18.0/go.mod h1:ateewQ5QbjMZF/dihEFXwaEwoA4v/mayRvzfmvb6eqI= k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= diff --git a/pkg/apis/dockhand.boxboat.io/v1alpha1/types.go b/pkg/apis/dockhand.boxboat.io/v1alpha1/types.go index 90d48b6..bfd9544 100644 --- a/pkg/apis/dockhand.boxboat.io/v1alpha1/types.go +++ b/pkg/apis/dockhand.boxboat.io/v1alpha1/types.go @@ -21,13 +21,18 @@ import ( ) const ( - AutoUpdateLabelKey = "dockhand.boxboat.io/autoUpdate" - DockhandSecretLabelKey = "dockhand.boxboat.io/ownedByDockhandSecret" - DockhandSecretNamesLabelPrefixKey = "dockhandsecret.boxboat.io/" - SecretNamesAnnotationKey = "dockhand.boxboat.io/secretNames" - SecretChecksumAnnotationKey = "dockhand.boxboat.io/secretChecksum" + AutoUpdateLabelKey = "dockhand.boxboat.io/autoUpdate" + DockhandSecretLabelKey = "dockhand.boxboat.io/ownedByDockhandSecret" + DockhandSecretNamesLabelPrefixKey = "dockhandsecret.boxboat.io/" + SecretNamesAnnotationKey = "dockhand.boxboat.io/secretNames" + SecretChecksumAnnotationKey = "dockhand.boxboat.io/secretChecksum" + Ready SecretState = "Ready" + Pending SecretState = "Pending" + ErrApplied SecretState = "ErrApplied" ) +type SecretState string + // SecretRef specifies a reference to a Secret type SecretRef struct { Name string `json:"name"` @@ -88,9 +93,10 @@ type DockhandSecret struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Data map[string]string `json:"data"` - SecretSpec SecretSpec `json:"secretSpec"` - Profile string `json:"profile"` + Data map[string]string `json:"data"` + SecretSpec SecretSpec `json:"secretSpec"` + Profile string `json:"profile"` + Status DockhandSecretStatus `json:"status,omitempty"` } // SecretSpec defines the kubernetes secret data to use for the secret managed by a DockhandSecret @@ -100,3 +106,7 @@ type SecretSpec struct { Labels map[string]string `json:"labels"` Annotations map[string]string `json:"annotations"` } + +type DockhandSecretStatus struct { + State SecretState `json:"state"` +} diff --git a/pkg/apis/dockhand.boxboat.io/v1alpha1/zz_generated_deepcopy.go b/pkg/apis/dockhand.boxboat.io/v1alpha1/zz_generated_deepcopy.go index f39a4dd..cf75c90 100644 --- a/pkg/apis/dockhand.boxboat.io/v1alpha1/zz_generated_deepcopy.go +++ b/pkg/apis/dockhand.boxboat.io/v1alpha1/zz_generated_deepcopy.go @@ -88,6 +88,7 @@ func (in *DockhandSecret) DeepCopyInto(out *DockhandSecret) { } } in.SecretSpec.DeepCopyInto(&out.SecretSpec) + out.Status = in.Status return } @@ -142,6 +143,22 @@ func (in *DockhandSecretList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockhandSecretStatus) DeepCopyInto(out *DockhandSecretStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockhandSecretStatus. +func (in *DockhandSecretStatus) DeepCopy() *DockhandSecretStatus { + if in == nil { + return nil + } + out := new(DockhandSecretStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DockhandSecretsProfile) DeepCopyInto(out *DockhandSecretsProfile) { *out = *in diff --git a/pkg/codegen/main.go b/pkg/codegen/main.go index faffd99..baf5f1f 100644 --- a/pkg/codegen/main.go +++ b/pkg/codegen/main.go @@ -21,7 +21,7 @@ import ( controllergen "github.com/rancher/wrangler/pkg/controller-gen" "github.com/rancher/wrangler/pkg/controller-gen/args" // Ensure gvk gets loaded in wrangler/pkg/gvk cache - _ "github.com/rancher/wrangler/pkg/generated/controllers/apiextensions.k8s.io/v1beta1" + _ "github.com/rancher/wrangler/pkg/generated/controllers/apiextensions.k8s.io/v1" ) func main() { diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index d6b5777..bf4ce78 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -119,6 +119,7 @@ func (h *Handler) onDockhandSecretRemove(_ string, secret *dockhand.DockhandSecr "could not delete secret=%s from namespace=%s", secret.SecretSpec.Name, secret.Namespace) + return nil, err } return nil, nil @@ -128,13 +129,29 @@ func (h *Handler) onDockhandSecretChange(_ string, secret *dockhand.DockhandSecr if secret == nil { return nil, nil } + + if secret.Status.State == "" { + statusErr := h.updateDockhandSecretStatus(secret, dockhand.Pending) + common.LogIfError(statusErr) + } + common.Log.Debugf("DockhandSecret change: %v", secret) profile, err := h.dhProfileCache.Get(h.operatorNamespace, secret.Profile) + if err != nil { - common.Log.Warnf("Could not load DockhandSecretsProfile[%s]", secret.Profile) - return nil, nil + common.Log.Warnf("Could not get DockhandSecretsProfile[%s]", secret.Profile) + h.recorder.Eventf(secret, corev1.EventTypeWarning, "ErrLoadingProfile", "Could not get DockhandSecretsProfile[%s]", secret.Profile) + statusErr := h.updateDockhandSecretStatus(secret, dockhand.ErrApplied) + common.LogIfError(statusErr) + return nil, err + } + + if err := h.loadDockhandSecretsProfile(profile); err != nil { + h.recorder.Eventf(secret, corev1.EventTypeWarning, "ErrLoadingProfile", "Could not load DockhandSecretsProfile: %v", err) + statusErr := h.updateDockhandSecretStatus(secret, dockhand.ErrApplied) + common.LogIfError(statusErr) + return nil, err } - h.loadDockhandSecretsProfile(profile) k8sSecret, err := h.secrets.Get(secret.Namespace, secret.SecretSpec.Name, metav1.GetOptions{}) @@ -179,6 +196,8 @@ func (h *Handler) onDockhandSecretChange(_ string, secret *dockhand.DockhandSecr secretData, err := dockcmdCommon.ParseSecretsTemplate([]byte(v), h.funcMap) if err != nil { h.recorder.Eventf(secret, corev1.EventTypeWarning, "ErrParsingSecret", "Could not parse template %v", err) + statusErr := h.updateDockhandSecretStatus(secret, dockhand.ErrApplied) + common.LogIfError(statusErr) return nil, err } common.Log.Debugf("%s: %s", k, secretData) @@ -189,56 +208,60 @@ func (h *Handler) onDockhandSecretChange(_ string, secret *dockhand.DockhandSecr if _, err := h.secrets.Create(k8sSecret); err == nil { h.recorder.Eventf(secret, corev1.EventTypeNormal, "Success", "Secret %s/%s created", secret.Namespace, secret.SecretSpec.Name) } else { + h.recorder.Eventf(secret, corev1.EventTypeWarning, "Error", "Secret %s/%s not created", secret.Namespace, secret.SecretSpec.Name) + statusErr := h.updateDockhandSecretStatus(secret, dockhand.ErrApplied) + common.LogIfError(statusErr) return nil, err } } else { if _, err := h.secrets.Update(k8sSecret); err == nil{ h.recorder.Eventf(secret, corev1.EventTypeNormal, "Success", "Secret %s/%s updated", secret.Namespace, secret.SecretSpec.Name) } else { + h.recorder.Eventf(secret, corev1.EventTypeWarning, "Error", "Secret %s/%s not updated", secret.Namespace, secret.SecretSpec.Name) + statusErr := h.updateDockhandSecretStatus(secret, dockhand.ErrApplied) + common.LogIfError(statusErr) return nil, err } } + // if we have made it here the secret is provisioned and ready + if err := h.updateDockhandSecretStatus(secret, dockhand.Ready); err != nil { + // log status update error but continue + common.LogIfError(err) + } + labelSelector := dockhand.DockhandSecretNamesLabelPrefixKey + secret.SecretSpec.Name - daemonsets, err := h.daemonSets.List(secret.Namespace, metav1.ListOptions{ - LabelSelector: labelSelector, - }) - if err != nil { - common.Log.Warnf("error listing deployments associated with %s: %v", labelSelector, err) - return nil, nil - } - for _, daemonset := range daemonsets.Items { - if _, err := h.processDaemonSet(&daemonset); err != nil { - common.Log.Warnf("error updating %s: %v", daemonset.Name, err) + if daemonsets, err := h.daemonSets.List(secret.Namespace, metav1.ListOptions{LabelSelector: labelSelector}); err == nil { + for _, daemonset := range daemonsets.Items { + if _, err := h.processDaemonSet(&daemonset); err != nil { + common.Log.Warnf("error updating %s: %v", daemonset.Name, err) + } } - } - - deployments, err := h.deployments.List(secret.Namespace, metav1.ListOptions{ - LabelSelector: labelSelector, - }) - if err != nil { + } else { common.Log.Warnf("error listing deployments associated with %s: %v", labelSelector, err) - return nil, nil - } - for _, deployment := range deployments.Items { - if _, err := h.processDeployment(&deployment); err != nil { - common.Log.Warnf("error updating %s: %v", deployment.Name, err) - } } - statefulsets, err := h.statefulSets.List(secret.Namespace, metav1.ListOptions{ - LabelSelector: labelSelector, - }) - if err != nil { + if deployments, err := h.deployments.List(secret.Namespace, metav1.ListOptions{LabelSelector: labelSelector}); err == nil { + for _, deployment := range deployments.Items { + if _, err := h.processDeployment(&deployment); err != nil { + common.Log.Warnf("error updating %s: %v", deployment.Name, err) + } + } + } else { common.Log.Warnf("error listing deployments associated with %s: %v", labelSelector, err) - return nil, nil } - for _, statefulset := range statefulsets.Items { - if _, err := h.processStatefulSet(&statefulset); err != nil { - common.Log.Warnf("error updating %s: %v", statefulset.Name, err) + + if statefulsets, err := h.statefulSets.List(secret.Namespace, metav1.ListOptions{LabelSelector: labelSelector}); err == nil { + for _, statefulset := range statefulsets.Items { + if _, err := h.processStatefulSet(&statefulset); err != nil { + common.Log.Warnf("error updating %s: %v", statefulset.Name, err) + } } + } else { + common.Log.Warnf("error listing deployments associated with %s: %v", labelSelector, err) } + return nil, nil } @@ -258,6 +281,7 @@ func (h *Handler) processDaemonSet(daemonset *v1.DaemonSet) (*v1.DaemonSet, erro if _, err := h.daemonSets.Patch(daemonset.GetNamespace(), daemonset.GetName(), types.JSONPatchType, patchBytes); err != nil { common.Log.Warnf("unable to update %s error:[%v]", daemonset.GetName(), err) + return nil, err } } } @@ -279,6 +303,7 @@ func (h *Handler) processDeployment(deployment *v1.Deployment) (*v1.Deployment, if _, err := h.deployments.Patch(deployment.GetNamespace(), deployment.GetName(), types.JSONPatchType, patchBytes); err != nil { common.Log.Warnf("unable to update %s error:[%v]", deployment.GetName(), err) + return nil, err } } } @@ -300,6 +325,7 @@ func (h *Handler) processStatefulSet(statefulset *v1.StatefulSet) (*v1.StatefulS if _, err := h.statefulSets.Patch(statefulset.GetNamespace(), statefulset.GetName(), types.JSONPatchType, patchBytes); err != nil { common.Log.Warnf("unable to update %s error:[%v]", statefulset.GetName(), err) + return nil, err } } } @@ -339,7 +365,10 @@ func (h *Handler) loadDockhandSecretsProfile(profile *dockhand.DockhandSecretsPr aws.AccessKeyID = *profile.AwsSecretsManager.AccessKeyId } if profile.AwsSecretsManager.SecretAccessKeyRef != nil { - secretData, _ := h.secrets.Get(h.operatorNamespace, profile.AwsSecretsManager.SecretAccessKeyRef.Name, metav1.GetOptions{}) + secretData, err := h.secrets.Get(h.operatorNamespace, profile.AwsSecretsManager.SecretAccessKeyRef.Name, metav1.GetOptions{}) + if err != nil { + return err + } if secretData != nil { aws.SecretAccessKey = string(secretData.Data[profile.AwsSecretsManager.SecretAccessKeyRef.Key]) } @@ -362,7 +391,10 @@ func (h *Handler) loadDockhandSecretsProfile(profile *dockhand.DockhandSecretsPr } if profile.AzureKeyVault.ClientSecretRef != nil { - secretData, _ := h.secrets.Get(h.operatorNamespace, profile.AzureKeyVault.ClientSecretRef.Name, metav1.GetOptions{}) + secretData, err := h.secrets.Get(h.operatorNamespace, profile.AzureKeyVault.ClientSecretRef.Name, metav1.GetOptions{}) + if err != nil { + return err + } if secretData != nil { azure.ClientSecret = string(secretData.Data[profile.AzureKeyVault.ClientSecretRef.Key]) } @@ -379,7 +411,10 @@ func (h *Handler) loadDockhandSecretsProfile(profile *dockhand.DockhandSecretsPr } gcp.Project = profile.GcpSecretsManager.Project if profile.GcpSecretsManager.CredentialsFileSecretRef != nil { - secretData, _ := h.secrets.Get(h.operatorNamespace, profile.GcpSecretsManager.CredentialsFileSecretRef.Name, metav1.GetOptions{}) + secretData, err := h.secrets.Get(h.operatorNamespace, profile.GcpSecretsManager.CredentialsFileSecretRef.Name, metav1.GetOptions{}) + if err != nil { + return err + } if secretData != nil { gcp.CredentialsJson = secretData.Data[profile.GcpSecretsManager.CredentialsFileSecretRef.Key] @@ -397,7 +432,10 @@ func (h *Handler) loadDockhandSecretsProfile(profile *dockhand.DockhandSecretsPr vault.RoleID = *profile.Vault.RoleId } if profile.Vault.SecretIdRef != nil { - secretData, _ := h.secrets.Get(h.operatorNamespace, profile.Vault.SecretIdRef.Name, metav1.GetOptions{}) + secretData, err := h.secrets.Get(h.operatorNamespace, profile.Vault.SecretIdRef.Name, metav1.GetOptions{}) + if err != nil { + return err + } if secretData != nil { vault.SecretID = string(secretData.Data["VAULT_SECRET_ID"]) } @@ -451,3 +489,12 @@ func (h *Handler) getUpdatedLabelsAndAnnotations( return updatedLabels, updatedAnnotations } + +func (h* Handler) updateDockhandSecretStatus(secret *dockhand.DockhandSecret, state dockhand.SecretState) error { + common.Log.Infof("Updating %s status", secret.Name) + secretCopy := secret.DeepCopy() + secretCopy.Status.State = state + _, err := h.dhSecretsController.UpdateStatus(secretCopy) + + return err +} diff --git a/pkg/generated/controllers/dockhand.boxboat.io/v1alpha1/dockhandsecret.go b/pkg/generated/controllers/dockhand.boxboat.io/v1alpha1/dockhandsecret.go index 4d33c1e..fa0ffd8 100644 --- a/pkg/generated/controllers/dockhand.boxboat.io/v1alpha1/dockhandsecret.go +++ b/pkg/generated/controllers/dockhand.boxboat.io/v1alpha1/dockhandsecret.go @@ -24,7 +24,10 @@ import ( v1alpha1 "github.com/boxboat/dockhand-secrets-operator/pkg/apis/dockhand.boxboat.io/v1alpha1" "github.com/rancher/lasso/pkg/client" "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/pkg/apply" + "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -54,7 +57,7 @@ type DockhandSecretController interface { type DockhandSecretClient interface { Create(*v1alpha1.DockhandSecret) (*v1alpha1.DockhandSecret, error) Update(*v1alpha1.DockhandSecret) (*v1alpha1.DockhandSecret, error) - + UpdateStatus(*v1alpha1.DockhandSecret) (*v1alpha1.DockhandSecret, error) Delete(namespace, name string, options *metav1.DeleteOptions) error Get(namespace, name string, options metav1.GetOptions) (*v1alpha1.DockhandSecret, error) List(namespace string, opts metav1.ListOptions) (*v1alpha1.DockhandSecretList, error) @@ -183,6 +186,11 @@ func (c *dockhandSecretController) Update(obj *v1alpha1.DockhandSecret) (*v1alph return result, c.client.Update(context.TODO(), obj.Namespace, obj, result, metav1.UpdateOptions{}) } +func (c *dockhandSecretController) UpdateStatus(obj *v1alpha1.DockhandSecret) (*v1alpha1.DockhandSecret, error) { + result := &v1alpha1.DockhandSecret{} + return result, c.client.UpdateStatus(context.TODO(), obj.Namespace, obj, result, metav1.UpdateOptions{}) +} + func (c *dockhandSecretController) Delete(namespace, name string, options *metav1.DeleteOptions) error { if options == nil { options = &metav1.DeleteOptions{} @@ -253,3 +261,115 @@ func (c *dockhandSecretCache) GetByIndex(indexName, key string) (result []*v1alp } return result, nil } + +type DockhandSecretStatusHandler func(obj *v1alpha1.DockhandSecret, status v1alpha1.DockhandSecretStatus) (v1alpha1.DockhandSecretStatus, error) + +type DockhandSecretGeneratingHandler func(obj *v1alpha1.DockhandSecret, status v1alpha1.DockhandSecretStatus) ([]runtime.Object, v1alpha1.DockhandSecretStatus, error) + +func RegisterDockhandSecretStatusHandler(ctx context.Context, controller DockhandSecretController, condition condition.Cond, name string, handler DockhandSecretStatusHandler) { + statusHandler := &dockhandSecretStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, FromDockhandSecretHandlerToHandler(statusHandler.sync)) +} + +func RegisterDockhandSecretGeneratingHandler(ctx context.Context, controller DockhandSecretController, apply apply.Apply, + condition condition.Cond, name string, handler DockhandSecretGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &dockhandSecretGeneratingHandler{ + DockhandSecretGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterDockhandSecretStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type dockhandSecretStatusHandler struct { + client DockhandSecretClient + condition condition.Cond + handler DockhandSecretStatusHandler +} + +func (a *dockhandSecretStatusHandler) sync(key string, obj *v1alpha1.DockhandSecret) (*v1alpha1.DockhandSecret, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type dockhandSecretGeneratingHandler struct { + DockhandSecretGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string +} + +func (a *dockhandSecretGeneratingHandler) Remove(key string, obj *v1alpha1.DockhandSecret) (*v1alpha1.DockhandSecret, error) { + if obj != nil { + return obj, nil + } + + obj = &v1alpha1.DockhandSecret{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +func (a *dockhandSecretGeneratingHandler) Handle(obj *v1alpha1.DockhandSecret, status v1alpha1.DockhandSecretStatus) (v1alpha1.DockhandSecretStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.DockhandSecretGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) +}