diff --git a/cmd/root.go b/cmd/root.go index 262b997..cefc4fb 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -65,6 +65,7 @@ func NewRootCommand(out io.Writer) (*cobra.Command, *RootOptions) { func AddDefaultArmadaCommands(cmd *cobra.Command, factory cfg.Factory) *cobra.Command { cmd.AddCommand(NewServerCommand(factory)) cmd.AddCommand(NewApplyCommand(factory)) + cmd.AddCommand(NewWaitCommand(factory)) return cmd } diff --git a/cmd/wait.go b/cmd/wait.go new file mode 100644 index 0000000..8dd460f --- /dev/null +++ b/cmd/wait.go @@ -0,0 +1,73 @@ +/* + 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 + + https://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 cmd + +import ( + "context" + "strconv" + "time" + + "github.com/spf13/cobra" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + "opendev.org/airship/armada-go/pkg/config" + "opendev.org/airship/armada-operator/pkg/waitutil" +) + +// NewWaitCommand creates a command to wait for armada manifests +func NewWaitCommand(_ config.Factory) *cobra.Command { + getConfig := func() *rest.Config { + k8sConfig, err := rest.InClusterConfig() + if err != nil { + k8sConfig, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + clientcmd.NewDefaultClientConfigLoadingRules(), &clientcmd.ConfigOverrides{}).ClientConfig() + if err != nil { + panic(err) + } + } + return k8sConfig + } + + var timeout string + p := &waitutil.WaitOptions{ + RestConfig: getConfig(), + } + + runCmd := &cobra.Command{ + Use: "wait", + Short: "armada-go command to wait for armada manifests", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + p.Logger = zap.New(zap.WriteTo(cmd.OutOrStdout()), zap.ConsoleEncoder()) + intTimeout, err := strconv.Atoi(timeout) + if err != nil { + return err + } + p.Timeout = time.Second * time.Duration(intTimeout) + return p.Wait(context.Background()) + }, + } + + flags := runCmd.Flags() + flags.StringVar(&p.ResourceType, "resource-type", "", "resource type") + flags.StringVar(&p.Namespace, "namespace", "", "namespace") + flags.StringVar(&p.LabelSelector, "label-selector", "", "label selector") + flags.StringVar(&timeout, "timeout", "", "timeout") + flags.StringVar(&p.MinReady, "min-ready", "", "min ready") + + return runCmd +} diff --git a/go.mod b/go.mod index dc733f1..cbff203 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,8 @@ require ( k8s.io/apimachinery v0.28.4 k8s.io/client-go v0.28.4 k8s.io/klog/v2 v2.100.1 - opendev.org/airship/armada-operator v0.0.0-20240131234736-165edb913367 + opendev.org/airship/armada-operator v0.0.0-20240207165352-d557f99c8fd2 + sigs.k8s.io/controller-runtime v0.16.3 sigs.k8s.io/yaml v1.4.0 ) @@ -23,6 +24,7 @@ require ( github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-logr/zapr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect @@ -51,6 +53,8 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.25.0 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/crypto v0.14.0 // indirect golang.org/x/net v0.17.0 // indirect @@ -66,7 +70,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect - sigs.k8s.io/controller-runtime v0.16.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect ) diff --git a/go.sum b/go.sum index 5267f93..2acef8e 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= @@ -21,6 +23,8 @@ github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SU github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= +github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -68,6 +72,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -91,7 +96,9 @@ github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -117,6 +124,16 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -125,13 +142,17 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= @@ -139,15 +160,20 @@ golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -158,9 +184,11 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -173,6 +201,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -198,8 +227,8 @@ k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5Ohx k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -opendev.org/airship/armada-operator v0.0.0-20240131234736-165edb913367 h1:Ae/TMu6lXzpF4KlLGpshu6oL9BZ8OwYYNGNvnLyBnVw= -opendev.org/airship/armada-operator v0.0.0-20240131234736-165edb913367/go.mod h1:0hmfND6t5ZuyHB3R7TmsAreqzF4vfc/q3LwX18gFldI= +opendev.org/airship/armada-operator v0.0.0-20240207165352-d557f99c8fd2 h1:rsAcpSOKKP6MdLWe/r+zi+zcx4alLjFxFYKw+CfcMPg= +opendev.org/airship/armada-operator v0.0.0-20240207165352-d557f99c8fd2/go.mod h1:0hmfND6t5ZuyHB3R7TmsAreqzF4vfc/q3LwX18gFldI= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= diff --git a/pkg/apply/apply.go b/pkg/apply/apply.go index 0d51fe4..879ef6f 100644 --- a/pkg/apply/apply.go +++ b/pkg/apply/apply.go @@ -45,8 +45,8 @@ import ( "sigs.k8s.io/yaml" "opendev.org/airship/armada-go/pkg/config" - armadawait "opendev.org/airship/armada-go/pkg/wait" armadav1 "opendev.org/airship/armada-operator/api/v1" + armadawait "opendev.org/airship/armada-operator/pkg/waitutil" ) // RunCommand phase run command @@ -130,8 +130,6 @@ func (c *RunCommand) RunE() error { Resource: armadav1.ArmadaChartPlural, }) - acClient := armadav1.NewForConfigOrDie(k8sConfig) - if err := c.CheckCRD(k8sConfig); err != nil { return err } @@ -146,7 +144,7 @@ func (c *RunCommand) RunE() error { chp := c.airCharts[cName] chpc := c.ConvertChart(chp) eg.Go(func() error { - return c.InstallChart(chpc, resClient, acClient) + return c.InstallChart(chpc, resClient, k8sConfig) }) } if err := eg.Wait(); err != nil { @@ -155,7 +153,7 @@ func (c *RunCommand) RunE() error { } else { for _, cName := range cg.ChartGroup { klog.V(5).Infof("sequential chart install %s", cName) - if err = c.InstallChart(c.ConvertChart(c.airCharts[cName]), resClient, acClient); err != nil { + if err = c.InstallChart(c.ConvertChart(c.airCharts[cName]), resClient, k8sConfig); err != nil { return err } } @@ -167,7 +165,7 @@ func (c *RunCommand) RunE() error { func (c *RunCommand) InstallChart( chart *armadav1.ArmadaChart, resClient dynamic.NamespaceableResourceInterface, - restConfig *rest.RESTClient) error { + restConfig *rest.Config) error { klog.V(5).Infof("installing chart %s %s %s", chart.GetName(), chart.Name, chart.Namespace) obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(chart) @@ -200,11 +198,11 @@ func (c *RunCommand) InstallChart( } wOpts := armadawait.WaitOptions{ - Getter: restConfig, - Namespace: chart.Namespace, + RestConfig: restConfig, + Namespace: chart.Namespace, LabelSelector: fmt.Sprintf("%s=%s", armadav1.ArmadaChartLabel, fmt.Sprintf("%s-%s", c.airManifest.ReleasePrefix, chart.Spec.Release)), - ResourceType: "armadacharts.armada.airshipit.io", + ResourceType: "armadacharts.armada.airshipit.org", Timeout: time.Second * time.Duration(chart.Spec.Wait.Timeout), Logger: klog.FromContext(context.Background()), } @@ -233,7 +231,7 @@ func (c *RunCommand) ConvertChart(chart *AirshipChart) *armadav1.ArmadaChart { func (c *RunCommand) CheckCRD(restConfig *rest.Config) error { crdClient := apiextension.NewForConfigOrDie(restConfig) - if _, err := crdClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.Background(), "armadacharts.armada.airshipit.io", metav1.GetOptions{}); err != nil { + if _, err := crdClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.Background(), "armadacharts.armada.airshipit.org", metav1.GetOptions{}); err != nil { if apierrors.IsNotFound(err) { klog.V(5).Infof("armadacharts CRD not found, creating: %s", err.Error()) objToapp, err := c.ReadCRD() diff --git a/pkg/wait/wait.go b/pkg/wait/wait.go deleted file mode 100644 index 1bc13dd..0000000 --- a/pkg/wait/wait.go +++ /dev/null @@ -1,147 +0,0 @@ -/* - 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 - - https://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 wait - -import ( - "context" - "errors" - "fmt" - "time" - - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/tools/cache" - watchtools "k8s.io/client-go/tools/watch" - - armadav1 "opendev.org/airship/armada-operator/api/v1" -) - -type StatusType string - -type Status struct { - StatusType - Msg string -} - -const ( - Ready StatusType = "READY" - Skipped StatusType = "SKIPPED" - Unready StatusType = "UNREADY" - Error StatusType = "ERROR" -) - -// WaitOptions phase run command -type WaitOptions struct { - Getter cache.Getter - Namespace string - LabelSelector string - ResourceType string - Timeout time.Duration - Logger logr.Logger -} - -func getObjectStatus(obj interface{}) Status { - switch v := obj.(type) { - case *armadav1.ArmadaChart: - return isArmadaChartReady(v) - default: - return Status{Error, fmt.Sprintf("Unable to cast an object to any type %s\n", obj)} - } -} - -func allMatch(logger logr.Logger, store cache.Store, obj runtime.Object) (bool, error) { - for _, item := range store.List() { - if obj != nil && item == obj { - continue - } - status := getObjectStatus(item) - logger.Info(fmt.Sprintf("all match object %T is ready returned %s\n", item, status.StatusType)) - logger.Info(status.Msg) - if status.StatusType != Ready && status.StatusType != Skipped { - logger.Info(fmt.Sprintf("all match exiting false due to %s\n", status.StatusType)) - return false, nil - } - } - logger.Info("all objects are ready\n") - return true, nil -} - -func processEvent(logger logr.Logger, event watch.Event) (StatusType, error) { - metaObj, err := meta.Accessor(event.Object) - if err != nil { - return Error, err - } - - logger.Info(fmt.Sprintf("watch event: type=%s, name=%s, namespace=%s, resource_ver %s", - event.Type, metaObj.GetName(), metaObj.GetNamespace(), metaObj.GetResourceVersion())) - - if event.Type == "ERROR" { - return Error, errors.New(fmt.Sprintf("resource %s: got error event %s", metaObj.GetName(), event.Object)) - } - - status := getObjectStatus(event.Object) - logger.Info(fmt.Sprintf("object type: %T, status: %s", event.Object, status.Msg)) - return status.StatusType, nil -} - -func isArmadaChartReady(ac *armadav1.ArmadaChart) Status { - if ac.Status.ObservedGeneration == ac.Generation { - for _, cond := range ac.Status.Conditions { - if cond.Type == "Ready" && cond.Status == "True" { - return Status{Ready, fmt.Sprintf("armadachart %s ready", ac.GetName())} - } - } - } - return Status{Unready, fmt.Sprintf("Waiting for armadachart %s to be ready", ac.GetName())} -} - -// Wait runs the phase -func (c *WaitOptions) Wait(parent context.Context) error { - c.Logger.Info(fmt.Sprintf("armada-go wait , namespace %s labels %s type %s timeout %s", c.Namespace, c.LabelSelector, c.ResourceType, c.Timeout)) - - ctx, cancelFunc := watchtools.ContextWithOptionalTimeout(parent, c.Timeout) - defer cancelFunc() - - lw := cache.NewFilteredListWatchFromClient(c.Getter, "armadacharts", c.Namespace, func(options *metav1.ListOptions) { - options.LabelSelector = c.LabelSelector - c.Logger.Info(fmt.Sprintf("Label selector applied %s", options)) - }) - - var cacheStore cache.Store - - cpu := func(store cache.Store) (bool, error) { - cacheStore = store - if len(store.List()) == 0 { - c.Logger.Info(fmt.Sprintf("skipping non-required wait, no resources found.\n")) - return true, nil - } - return allMatch(c.Logger, cacheStore, nil) - } - - cfu := func(event watch.Event) (bool, error) { - if ready, err := processEvent(c.Logger, event); ready != Ready || err != nil { - return false, err - } - - return allMatch(c.Logger, cacheStore, event.Object) - } - - _, err := watchtools.UntilWithSync(ctx, lw, nil, cpu, cfu) - c.Logger.Info(fmt.Sprintf("wait completed %s\n", c.LabelSelector)) - return err -}