diff --git a/Makefile b/Makefile index 52b7611ac..b2aa53b66 100644 --- a/Makefile +++ b/Makefile @@ -16,13 +16,13 @@ #all: test -.PHONY: ibm-block-csi-operator -ibm-block-csi-operator: +.PHONY: build +build: CGO_ENABLED=1 GOOS=linux go build -o build/_output/bin/ibm-block-csi-operator -gcflags all=-trimpath=${GOPATH} -asmflags all=-trimpath=${GOPATH} -mod=vendor cmd/manager/main.go .PHONY: test test: update - # for go 1.13+, set GOFLAGS to enable vendor mod + # for go 1.13+, set GOFLAGS to enable vendor mod for ginkgo GO111MODULE=on GOFLAGS='-mod=vendor' ginkgo -r -skipPackage pkg/controller .PHONY: update diff --git a/NOTICES b/NOTICES index 07da69947..a1c22b8e4 100644 --- a/NOTICES +++ b/NOTICES @@ -5,7 +5,7 @@ This file details additional third party software license agreements and third party notices and information that are required to be reproduced for the following programs: -Operator for IBM Block Storage CSI Driver version 1.0.0 +Operator for IBM Block Storage CSI Driver version 1.1.0 @@ -1040,7 +1040,7 @@ Version 7 =========================================================================== END OF TERMS AND CONDITIONS FOR SEPARATELY LICENSED CODE for Operator for -IBM Block Storage CSI Driver version 1.0.0 +IBM Block Storage CSI Driver version 1.1.0 =========================================================================== @@ -1051,7 +1051,7 @@ IBM Block Storage CSI Driver version 1.0.0 GNU GPL and / or LGPL Source Code for: -Operator for IBM Block Storage CSI Driver Version 1.0.0 Third Party +Operator for IBM Block Storage CSI Driver Version 1.1.0 Third Party Licenses and Notices =========================================================================== @@ -1063,24 +1063,24 @@ Licenses and Notices @@@@@@@@@@@@ =========================================================================== Lesser General Public License version 3.0: The product includes the -following licensed code to the licensee as Separately Licensed Code under -the GNU Lesser General Public License 3.0. +following licensed code to the licensee as Separately Licensed Code +under the GNU Lesser General Public License 3.0. =========================================================================== Prometheus version 1.8.2 -Source code to any of the above-listed packages distributed with Operator -for IBM Block Storage CSI Driver Version 1.0.0 Third Party Licenses and -Notices is available at the website below, when a URL is provided, or by -sending a request to the following address or email: +Source code to any of the above-listed packages distributed with +Operator for IBM Block Storage CSI Driver Version 1.1.0 Third Party +Licenses and Notices is available at the website below, when a URL is +provided, or by sending a request to the following address or email: IBM Corporation Attn: Dept 4XNA / 9032-2, Storage Open Source Management 9000 S. Rita Road Tucson, AZ 85744 -Please identify the name of the IBM product and the GPL or LGPL licensed -program(s) required in the request for source code. +Please identify the name of the IBM product and the GPL or LGPL +licensed program(s) required in the request for source code. =========================================================================== END of GNU LGPL Version 3.0 Notices and Information @@ -1117,6 +1117,7 @@ APACHE 2.0 LICENSED CODE: The Program includes all or portions of the following software which IBM obtained under the terms and conditions of the Apache License Version 2.0: +apiextensions-apiserver version 1.1.14 api-kubernetes version 1.14.1 apimacherniery-kubernetes version 1.14.1 cloud-provider-kubernetes version 1.14.1 @@ -1135,8 +1136,6 @@ prometheus version 1.8.2 spec version 0.17.2 thrift ---------------------------------------------------------------------------- - --------------------------------------------------------------------------- Start of Apache Software License Version 2.0 --------------------------------------------------------------------------- @@ -1348,8 +1347,103 @@ End of Apache Software License Version 2.0 --------------------------------------------------------------------------- + +=========================================================================== +NOTICE file corresponding to section 4(d) of the Apache License, +Version 2.0, in this case for the apiextensions-apiserver +version 1.1.14 distribution +=========================================================================== +CoreOS Project +Copyright 2014 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). + +--------------------------------------------------------------------------- +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. + +--------------------------------------------------------------------------- + +CoreOS Project +Copyright 2014 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). + +--------------------------------------------------------------------------- + +Copyright 2012 Matt T. Proud (matt.proud@gmail.com) + +--------------------------------------------------------------------------- + +Prometheus instrumentation library for Go applications +Copyright 2012-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + + +The following components are included in this product: + +perks - a fork of https://github.com/bmizerany/perks +https://github.com/beorn7/perks +Copyright 2013-2015 Blake Mizerany, Björn Rabenstein +See https://github.com/beorn7/perks/blob/master/README.md for license details. + +Go support for Protocol Buffers - Google's data interchange format +http://github.com/golang/protobuf/ +Copyright 2010 The Go Authors +See source code for license details. + +Support for streaming Protocol Buffer messages for the Go language (golang). +https://github.com/matttproud/golang_protobuf_extensions +Copyright 2013 Matt T. Proud +Licensed under the Apache License, Version 2.0 + +--------------------------------------------------------------------------- + +Data model artifacts for Prometheus. +Copyright 2012-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + +--------------------------------------------------------------------------- + +Common libraries shared by Prometheus Go components. +Copyright 2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + +--------------------------------------------------------------------------- + +procfs provides functions to retrieve system, kernel and process +metrics from the pseudo-filesystem proc. + +Copyright 2014-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + --------------------------------------------------------------------------- +Copyright 2011-2016 Canonical 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. =========================================================================== @@ -1549,175 +1643,1095 @@ Version 2.0, in this case for the prometheus version 1.8.2 distribution The Prometheus systems and service monitoring server Copyright 2012-2015 The Prometheus Authors -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + + +The following components are included in this product: + +Bootstrap +http://getbootstrap.com +Copyright 2011-2014 Twitter, Inc. +Licensed under the MIT License + +bootstrap3-typeahead.js +https://github.com/bassjobsen/Bootstrap-3-Typeahead +Original written by @mdo and @fat +Copyright 2014 Bass Jobsen @bassjobsen +Licensed under the Apache License, Version 2.0 + +fuzzy +https://github.com/mattyork/fuzzy +Original written by @mattyork +Copyright 2012 Matt York +Licensed under the MIT License + +bootstrap-datetimepicker.js +https://github.com/Eonasdan/bootstrap-datetimepicker +Copyright 2015 Jonathan Peterson (@Eonasdan) +Licensed under the MIT License + +moment.js +https://github.com/moment/moment/ +Copyright JS Foundation and other contributors +Licensed under the MIT License + +Rickshaw +https://github.com/shutterstock/rickshaw +Copyright 2011-2014 by Shutterstock Images, LLC +See https://github.com/shutterstock/rickshaw/blob/master/LICENSE for +license details + +mustache.js +https://github.com/janl/mustache.js +Copyright 2009 Chris Wanstrath (Ruby) +Copyright 2010-2014 Jan Lehnardt (JavaScript) +Copyright 2010-2015 The mustache.js community +Licensed under the MIT License + +jQuery +https://jquery.org +Copyright jQuery Foundation and other contributors +Licensed under the MIT License + +Go support for Protocol Buffers - Google's data interchange format +http://github.com/golang/protobuf/ +Copyright 2010 The Go Authors +See source code for license details. + +Go support for leveled logs, analogous to +https://code.google.com/p/google-glog/ +Copyright 2013 Google Inc. +Licensed under the Apache License, Version 2.0 + +Support for streaming Protocol Buffer messages for the Go language (golang). +https://github.com/matttproud/golang_protobuf_extensions +Copyright 2013 Matt T. Proud +Licensed under the Apache License, Version 2.0 + +DNS library in Go +http://miek.nl/posts/2014/Aug/16/go-dns-package/ +Copyright 2009 The Go Authors, 2011 Miek Gieben +See https://github.com/miekg/dns/blob/master/LICENSE for +license details. + +LevelDB key/value database in Go +https://github.com/syndtr/goleveldb +Copyright 2012 Suryandaru Triandana +See https://github.com/syndtr/goleveldb/blob/master/LICENSE for +license details. + +gosnappy - a fork of code.google.com/p/snappy-go +https://github.com/syndtr/gosnappy +Copyright 2011 The Snappy-Go Authors +See https://github.com/syndtr/gosnappy/blob/master/LICENSE for +license details. + +go-zookeeper - Native ZooKeeper client for Go +https://github.com/samuel/go-zookeeper +Copyright (c) 2013, Samuel Stauffer +See https://github.com/samuel/go-zookeeper/blob/master/LICENSE for license +details. + +--------------------------------------------------------------------------- + +AWS SDK for Go +Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Copyright 2014-2015 Stripe, Inc. + +--------------------------------------------------------------------------- + +Copyright 2012 Matt T. Proud (matt.proud@gmail.com) + +--------------------------------------------------------------------------- + +Prometheus instrumentation library for Go applications +Copyright 2012-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + + +The following components are included in this product: + +perks - a fork of https://github.com/bmizerany/perks +https://github.com/beorn7/perks +Copyright 2013-2015 Blake Mizerany, Björn Rabenstein +See https://github.com/beorn7/perks/blob/master/README.md for license details. + +Go support for Protocol Buffers - Google's data interchange format +http://github.com/golang/protobuf/ +Copyright 2010 The Go Authors +See source code for license details. + +Support for streaming Protocol Buffer messages for the Go language (golang). +https://github.com/matttproud/golang_protobuf_extensions +Copyright 2013 Matt T. Proud +Licensed under the Apache License, Version 2.0 + +--------------------------------------------------------------------------- + +Data model artifacts for Prometheus. +Copyright 2012-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + +--------------------------------------------------------------------------- + +Common libraries shared by Prometheus Go components. +Copyright 2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + +--------------------------------------------------------------------------- + +procfs provides functions to retrieve system, kernel and process +metrics from the pseudo-filesystem proc. + +Copyright 2014-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + + +=========================================================================== +NOTICE file corresponding to section 4(d) of the Apache License, +Version 2.0, in this case for the thrift distribution +=========================================================================== +Apache Thrift +Copyright (C) 2006 - 2019, The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=========================================================================== +END OF APACHE 2.0 NOTICES AND INFORMATION +=========================================================================== + + + +@@@@@@@@@@@@ +=========================================================================== +apiextensions-apiserver version 1.1.14: The Program includes +apiextensions-apiserver version 1.1.14 software. IBM obtained +portions of the apiextensions-apiserver version 1.1.14 software under +the terms and conditions of the following license(s): +--------------------------------------------------------------------------- + +Copyright (c) 2009-2019 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +* Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +The MIT License (MIT) + +Copyright (c) 2014 Sam Ghods + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2012 Alex Ogier. All rights reserved. +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +* Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +Copyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go +Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +* Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +Copyright (c) 2016-2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2009 The oauth2 Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +* Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +The MIT License (MIT) + +Copyright (c) 2012-2015 Ugorji Nwoke. +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (C) 2013 Blake Mizerany + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------- + +The MIT License (MIT) + +Copyright (c) 2013 Ben Johnson + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2009,2014 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +* Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +Copyright (c) 2013 Dario Castañé. All rights reserved. +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +* Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +Copyright (c) 2006 Kirill Simonov + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2010-2013 - Gustavo Niemeyer + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +ISC License + +Copyright (c) 2012-2016 Dave Collins + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright 2010 The Go Authors. All rights reserved. +https://github.com/golang/protobuf + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +* Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +Copyright (c) 2016 Mail.Ru Group + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2014 Simon Eskildsen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2015 Xiang Li + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2012 Dave Grijalva + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------- +MIT License + +Copyright (c) 2016 json-iterator + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell + +Please consider promoting this project if you find it useful. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +Copyright (c) 2012, Martin Angers +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used +to endorse or promote products derived from this software without specific prior +written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +Copyright (c) 2014, Evan Phoenix +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +* Neither the name of the Evan Phoenix nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +Copyright (c) 2013, Patrick Mezard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +The names of its contributors may not be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +Copyright (c) 2012,2013 Ernest Micklei + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2010-2012 - Gustavo Niemeyer + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + +Copyright (c) 2014 Nate Finch + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--------------------------------------------------------------------------- +Copyright (c) 2014 Alex Saskevich -The following components are included in this product: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -Bootstrap -http://getbootstrap.com -Copyright 2011-2014 Twitter, Inc. -Licensed under the MIT License +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -bootstrap3-typeahead.js -https://github.com/bassjobsen/Bootstrap-3-Typeahead -Original written by @mdo and @fat -Copyright 2014 Bass Jobsen @bassjobsen -Licensed under the Apache License, Version 2.0 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. -fuzzy -https://github.com/mattyork/fuzzy -Original written by @mattyork -Copyright 2012 Matt York -Licensed under the MIT License +--------------------------------------------------------------------------- -bootstrap-datetimepicker.js -https://github.com/Eonasdan/bootstrap-datetimepicker -Copyright 2015 Jonathan Peterson (@Eonasdan) -Licensed under the MIT License +Copyright (c) 2013 Mitchell Hashimoto -moment.js -https://github.com/moment/moment/ -Copyright JS Foundation and other contributors -Licensed under the MIT License +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -Rickshaw -https://github.com/shutterstock/rickshaw -Copyright 2011-2014 by Shutterstock Images, LLC -See https://github.com/shutterstock/rickshaw/blob/master/LICENSE for -license details +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. -mustache.js -https://github.com/janl/mustache.js -Copyright 2009 Chris Wanstrath (Ruby) -Copyright 2010-2014 Jan Lehnardt (JavaScript) -Copyright 2010-2015 The mustache.js community -Licensed under the MIT License +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. -jQuery -https://jquery.org -Copyright jQuery Foundation and other contributors -Licensed under the MIT License +--------------------------------------------------------------------------- -Go support for Protocol Buffers - Google's data interchange format -http://github.com/golang/protobuf/ -Copyright 2010 The Go Authors -See source code for license details. +Copyright (C) 2016 Travis Cline -Go support for leveled logs, analogous to -https://code.google.com/p/google-glog/ -Copyright 2013 Google Inc. -Licensed under the Apache License, Version 2.0 +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: -Support for streaming Protocol Buffer messages for the Go language (golang). -https://github.com/matttproud/golang_protobuf_extensions -Copyright 2013 Matt T. Proud -Licensed under the Apache License, Version 2.0 +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -DNS library in Go -http://miek.nl/posts/2014/Aug/16/go-dns-package/ -Copyright 2009 The Go Authors, 2011 Miek Gieben -See https://github.com/miekg/dns/blob/master/LICENSE for -license details. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -LevelDB key/value database in Go -https://github.com/syndtr/goleveldb -Copyright 2012 Suryandaru Triandana -See https://github.com/syndtr/goleveldb/blob/master/LICENSE for -license details. +--------------------------------------------------------------------------- -gosnappy - a fork of code.google.com/p/snappy-go -https://github.com/syndtr/gosnappy -Copyright 2011 The Snappy-Go Authors -See https://github.com/syndtr/gosnappy/blob/master/LICENSE for -license details. +Copyright (c) 2015, Gengo, Inc. +All rights reserved. -go-zookeeper - Native ZooKeeper client for Go -https://github.com/samuel/go-zookeeper -Copyright (c) 2013, Samuel Stauffer -See https://github.com/samuel/go-zookeeper/blob/master/LICENSE for license -details. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: ---------------------------------------------------------------------------- +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. -AWS SDK for Go -Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. -Copyright 2014-2015 Stripe, Inc. +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. ---------------------------------------------------------------------------- +* Neither the name of Gengo, Inc. nor the names of its +contributors may be used to endorse or promote products derived from this +software without specific prior written permission. -Copyright 2012 Matt T. Proud (matt.proud@gmail.com) +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- -Prometheus instrumentation library for Go applications -Copyright 2012-2015 The Prometheus Authors - -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). - +Copyright ©2013 The Gonum Authors. All rights reserved. -The following components are included in this product: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +* Neither the name of the gonum project nor the names of its authors and +contributors may be used to endorse or promote products derived from this +software without specific prior written permission. -perks - a fork of https://github.com/bmizerany/perks -https://github.com/beorn7/perks -Copyright 2013-2015 Blake Mizerany, Björn Rabenstein -See https://github.com/beorn7/perks/blob/master/README.md for license details. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Go support for Protocol Buffers - Google's data interchange format -http://github.com/golang/protobuf/ -Copyright 2010 The Go Authors -See source code for license details. +--------------------------------------------------------------------------- -Support for streaming Protocol Buffer messages for the Go language (golang). -https://github.com/matttproud/golang_protobuf_extensions -Copyright 2013 Matt T. Proud -Licensed under the Apache License, Version 2.0 +Copyright (c) 2016, The GoGo Authors. All rights reserved. +Copyright (c) 2015, The GoGo Authors. All rights reserved. +Copyright (c) 2013, The GoGo Authors. All rights reserved. +http://github.com/gogo/protobuf ---------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: -Data model artifacts for Prometheus. -Copyright 2012-2015 The Prometheus Authors + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- -Common libraries shared by Prometheus Go components. -Copyright 2015 The Prometheus Authors +Copyright (c) 2011, Open Knowledge Foundation Ltd. +All rights reserved. -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: ---------------------------------------------------------------------------- + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. -procfs provides functions to retrieve system, kernel and process -metrics from the pseudo-filesystem proc. + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. -Copyright 2014-2015 The Prometheus Authors + Neither the name of the Open Knowledge Foundation Ltd. nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -=========================================================================== -NOTICE file corresponding to section 4(d) of the Apache License, -Version 2.0, in this case for the thrift distribution -=========================================================================== -Apache Thrift -Copyright (C) 2006 - 2019, The Apache Software Foundation -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). - =========================================================================== -END OF APACHE 2.0 NOTICES AND INFORMATION +END OF apiextensions-apiserver version 1.1.14 NOTICES AND INFORMATION =========================================================================== - @@@@@@@@@@@@ =========================================================================== code-generator-kubernetes version 1.13.1: The Program includes @@ -3045,8 +4059,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =========================================================================== -END OF prometheus-operator version 0.31.1 NOTICES AND -INFORMATION +END OF prometheus-operator version 0.31.1 NOTICES AND INFORMATION =========================================================================== @@ -3983,7 +4996,7 @@ END OF thrift NOTICES AND INFORMATION =========================================================================== END OF NOTICES AND INFORMATION FOR Operator for IBM Block -Storage CSI Driver Version 1.0.0 Third Party Licenses and +Storage CSI Driver Version 1.1.0 Third Party Licenses and Notices =========================================================================== diff --git a/README.md b/README.md index 8261b4935..63c3785f8 100644 --- a/README.md +++ b/README.md @@ -5,18 +5,22 @@ This is the official operator to deploy and manage IBM block storage CSI driver. Supported container platforms: - OpenShift v4.2 + - OpenShift v4.3 - Kubernetes v1.14 + - Kubernetes v1.16 Supported IBM storage systems: - IBM FlashSystem 9100 - - IBM Spectrum Virtualize - - IBM Storwize + - IBM Spectrum Virtualize Family (including IBM Flash family members built with IBM Spectrum Virtualize (FlashSystem 5010, 5030, 5100, 7200, 9100, 9200, 9200R) and IBM SAN Volume Controller (SVC) models SV2, SA2) - IBM FlashSystem A9000/R + - IBM DS8880 + - IBM DS8900 Supported operating systems: - RHEL 7.x (x86 architecture) + - RHCOS (x86 and IBM Z architecture) -Full documentation can be found on the [IBM knowledge center](https://www.ibm.com/support/knowledgecenter/SSRQ8T). +Full documentation can be found on the [IBM Knowledge Center](https://www.ibm.com/support/knowledgecenter/SSRQ8T).

@@ -28,8 +32,8 @@ Full documentation can be found on the [IBM knowledge center](https://www.ibm.co ### Preparing worker nodes Perform these steps for each worker node in Kubernetes cluster: -#### 1. Install Linux packages to ensure Fibre Channel and iSCSI connectivity -Skip this step if the packages are already installed. +#### 1. Perform this step to ensure iSCSI connectivity, when using RHEL OS. +If using RHCOS or if the packages are already installed, continue to the next step. RHEL 7.x: ```bash @@ -37,12 +41,87 @@ yum -y install iscsi-initiator-utils # Only if iSCSI connectivity is required yum -y install xfsprogs # Only if XFS file system is required ``` -#### 2. Configure Linux multipath devices on the host -Create and set the relevant storage system parameters in the `/etc/multipath.conf` file. -You can also use the default `multipath.conf` file, located in the `/usr/share/doc/device-mapper-multipath-*` directory. -Verify that the `systemctl status multipathd` output indicates that the multipath status is active and error-free. +#### 2. Configure Linux multipath devices on the host, using one of the following procedures. + +##### 2.1 Configuring for OpenShift Container Platform users (RHEL and RHCOS) + +The following yaml file example is for both Fibre Channel and iSCSI configurations. To support iSCSI, uncomment the last two lines in the file: + + +**Important:** The `99-ibm-attach.yaml` configuration file overrides any files that already exist on your system. Only use this file if the files mentioned in the yaml below are not already created. If one or more have been created, edit this yaml file, as necessary. + +Save the `99-ibm-attach.yaml` file. + +```bash +apiVersion: machineconfiguration.openshift.io/v1 +kind: MachineConfig +metadata: +labels: +machineconfiguration.openshift.io/role: worker +name: 99-ibm-attach +spec: +config: +ignition: +version: 2.2.0 +storage: +files: +- path: /etc/multipath.conf +mode: 384 +filesystem: root +contents: +source: data:,defaults%20%7B%0A%20%20%20%20path_checker%20tur%0A%20%20%20%20path_selector +%20%22round-robin%200%22%0A%20%20%20%20rr_weight%20uniform%0A%20%20%20%20prio%20const%0A +%20%20%20%20rr_min_io_rq%201%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20polling_interval +%2030%0A%20%20%20%20path_grouping_policy%20multibus%0A%20%20%20%20find_multipaths%20yes%0A +%20%20%20%20no_path_retry%20fail%0A%20%20%20%20user_friendly_names%20yes%0A%20%20%20%20failback +%20immediate%0A%20%20%20%20checker_timeout%2010%0A%20%20%20%20fast_io_fail_tmo%20off%0A%7D%0A%0Adevices +%20%7B%0A%20%20%20%20device%20%7B%0A%20%20%20%20%20%20%20%20path_checker%20tur%0A +%20%20%20%20%20%20%20%20product%20%22FlashSystem%22%0A%20%20%20%20%20%20%20%20vendor%20%22IBM%22%0A +%20%20%20%20%20%20%20%20rr_weight%20uniform%0A%20%20%20%20%20%20%20%20rr_min_io_rq +%204%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20path_grouping_policy +%20multibus%0A%20%20%20%20%20%20%20%20path_selector%20%22round-robin%200%22%0A +%20%20%20%20%20%20%20%20no_path_retry%20fail%0A%20%20%20%20%20%20%20%20failback%20immediate%0A +%20%20%20%20%7D%0A%20%20%20%20device%20%7B%0A%20%20%20%20%20%20%20%20path_checker%20tur%0A +%20%20%20%20%20%20%20%20product%20%22FlashSystem-9840%22%0A%20%20%20%20%20%20%20%20vendor%20%22IBM%22%0A +%20%20%20%20%20%20%20%20fast_io_fail_tmo%20off%0A%20%20%20%20%20%20%20%20rr_weight%20uniform%0A +%20%20%20%20%20%20%20%20rr_min_io_rq%201000%20%20%20%20%20%20%20%20%20%20%20%20%0A +%20%20%20%20%20%20%20%20path_grouping_policy%20multibus%0A%20%20%20%20%20%20%20%20path_selector +%20%22round-robin%200%22%0A%20%20%20%20%20%20%20%20no_path_retry%20fail%0A +%20%20%20%20%20%20%20%20failback%20immediate%0A%20%20%20%20%7D%0A%20%20%20%20device%20%7B%0A +%20%20%20%20%20%20%20%20vendor%20%22IBM%22%0A%20%20%20%20%20%20%20%20product%20%222145%22%0A +%20%20%20%20%20%20%20%20path_checker%20tur%0A%20%20%20%20%20%20%20%20features%20%221%20queue_if_no_path +%22%0A%20%20%20%20%20%20%20%20path_grouping_policy%20group_by_prio%0A +%20%20%20%20%20%20%20%20path_selector%20%22service-time%200%22%20%23%20Used%20by%20Red%20Hat%207.x%0A +%20%20%20%20%20%20%20%20prio%20alua%0A%20%20%20%20%20%20%20%20rr_min_io_rq%201%0A +%20%20%20%20%20%20%20%20rr_weight%20uniform%20%0A%20%20%20%20%20%20%20%20no_path_retry%20%225%22%0A +%20%20%20%20%20%20%20%20dev_loss_tmo%20120%0A%20%20%20%20%20%20%20%20failback%20immediate%0A%20%20%20%7D +%0A%7D%0A +verification: {} +- path: /etc/udev/rules.d/99-ibm-2145.rules +mode: 420 +filesystem: root +contents: +source: data:,%23%20Set%20SCSI%20command%20timeout%20to%20120s%20%28default%20%3D%3D +%2030%20or%2060%29%20for%20IBM%202145%20devices%0ASUBSYSTEM%3D%3D%22block%22%2C%20ACTION%3D%3D%22add +%22%2C%20ENV%7BID_VENDOR%7D%3D%3D%22IBM%22%2CENV%7BID_MODEL%7D%3D%3D%222145%22%2C%20RUN%2B%3D%22/bin/sh +%20-c%20%27echo%20120%20%3E/sys/block/%25k/device/timeout%27%22%0A +verification: {} +systemd: +units: +- name: multipathd.service +enabled: true +# Uncomment the following lines if this MachineConfig will be used with iSCSI connectivity +#- name: iscsid.service +# enabled: true +``` + +Apply the yaml file. +```bash +oc apply -f 99-ibm-attach.yaml +``` + +RHEL users should verify that the `systemctl status multipathd` output indicates that the multipath status is active and error-free. -RHEL 7.x: ```bash yum install device-mapper-multipath modprobe dm-multipath @@ -52,36 +131,24 @@ systemctl status multipathd multipath -ll ``` -**Important:** When configuring Linux multipath devices, verify that the `find_multipaths` parameter in the `multipath.conf` file is disabled. In RHEL 7.x, remove the`find_multipaths yes` string from the `multipath.conf` file. +##### 2.2 Configuring for Kubernetes users (RHEL) +Create and set the relevant storage system parameters in the `/etc/multipath.conf` file. You can also use the default `multipath.conf` file, located in the `/usr/share/doc/device-mapper-multipath-*` directory. -#### 3. Configure storage system connectivity -3.1. Define the hostname of each Kubernetes node on the relevant storage systems with the valid WWPN(for Fibre Channel) or IQN(for iSCSI) of the node. - -3.2. For Fibre Channel, configure the relevant zoning from the storage to the host. - -3.3. For iSCSI, perform the following steps: - -3.3.1. Make sure that the login to the iSCSI targets is permanent and remains available after a reboot of the worker node. To do this, verify that the node.startup in the /etc/iscsi/iscsid.conf file is set to automatic. If not, set it as required and then restart the iscsid service `$ service iscsid restart`. - -3.3.2. Discover and log into at least two iSCSI targets on the relevant storage systems. (NOTE: Without at least two ports, multipath device will not be created.) +Verify that the `systemctl status multipathd` output indicates that the multipath status is active and error-free. ```bash -$ iscsiadm -m discoverydb -t st -p ${STORAGE-SYSTEM-iSCSI-PORT-IP1}:3260 --discover -$ iscsiadm -m node -p ${STORAGE-SYSTEM-iSCSI-PORT-IP1} --login - -$ iscsiadm -m discoverydb -t st -p ${STORAGE-SYSTEM-iSCSI-PORT-IP2}:3260 --discover -$ iscsiadm -m node -p ${STORAGE-SYSTEM-iSCSI-PORT-IP2} --login +yum install device-mapper-multipath +modprobe dm-multipath +systemctl enable multipathd +systemctl start multipathd +systemctl status multipathd +multipath -ll ``` -3.3.3. Verify that the login was successful and display all targets that you logged into. The portal value must be the iSCSI target IP address. - -```bash -$ iscsiadm -m session --rescan -Rescanning session [sid: 1, target: {storage system IQN}, -portal: {STORAGE-SYSTEM-iSCSI-PORT-IP1},{port number} -portal: {STORAGE-SYSTEM-iSCSI-PORT-IP2},{port number} -``` +#### 3. Configure storage system connectivity +3.1. Define the hostname of each Kubernetes node on the relevant storage systems with the valid WWPN(for Fibre Channel) or IQN(for iSCSI) of the node. +3.2. For Fibre Channel, configure the relevant zoning from the storage to the host.
@@ -94,23 +161,31 @@ portal: {STORAGE-SYSTEM-iSCSI-PORT-IP2},{port number} ### Install the operator +#### 1. Download the manifest from GitHub. -1. Download the manifest from GitHub. ```bash curl https://raw.githubusercontent.com/IBM/ibm-block-csi-operator/master/deploy/installer/generated/ibm-block-csi-operator.yaml > ibm-block-csi-operator.yaml ``` -2. (Optional): If required, update the image fields in the ibm-block-csi-operator.yaml. -3. Install the operator. +#### 2. (Optional): If required, update the image fields in the ibm-block-csi-operator.yaml. + + +#### 3. Create a namespace. + +```bash +$ kubectl create ns +``` + +#### 4. Install the operator, while using a user-defined namespace. ```bash -$ kubectl apply -f ibm-block-csi-operator.yaml +$ kubectl -n apply -f ibm-block-csi-operator.yaml ``` ### Verify the operator is running: ```bash -$ kubectl get pod -l app.kubernetes.io/name=ibm-block-csi-operator -n kube-system +$ kubectl get pod -l app.kubernetes.io/name=ibm-block-csi-operator -n NAME READY STATUS RESTARTS AGE ibm-block-csi-operator-5bb7996b86-xntss 2/2 Running 0 10m ``` @@ -118,23 +193,23 @@ ibm-block-csi-operator-5bb7996b86-xntss 2/2 Running 0 10m ### Create an IBMBlockCSI custom resource -1. Download the manifest from GitHub. +#### 1. Download the manifest from GitHub. ```bash curl https://raw.githubusercontent.com/IBM/ibm-block-csi-operator/master/deploy/crds/csi.ibm.com_v1_ibmblockcsi_cr.yaml > csi.ibm.com_v1_ibmblockcsi_cr.yaml ``` -2. (Optional): If required, update the image fields in the csi.ibm.com_v1_ibmblockcsi_cr.yaml. +#### 2. (Optional): If required, update the image fields in the csi.ibm.com_v1_ibmblockcsi_cr.yaml. -3. Install the csi.ibm.com_v1_ibmblockcsi_cr.yaml. +#### 3. Install the csi.ibm.com_v1_ibmblockcsi_cr.yaml. ```bash -$ kubectl apply -f csi.ibm.com_v1_ibmblockcsi_cr.yaml +$ kubectl -n apply -f csi.ibm.com_v1_ibmblockcsi_cr.yaml ``` ### Verify the driver is running: ```bash -$ kubectl get all -n kube-system -l csi +$ kubectl get all -n -l csi NAME READY STATUS RESTARTS AGE pod/ibm-block-csi-controller-0 4/4 Running 0 9m36s pod/ibm-block-csi-node-jvmvh 3/3 Running 0 9m36s @@ -158,7 +233,7 @@ In order to use the driver, create the relevant storage classes and secrets, as This section describes how to: 1. Create a storage system secret - to define the storage system credentials (user and password) and its address. - 2. Configure the k8s storage class - to define the storage system pool name, secret reference, SpaceEfficiency (thin, compressed, or deduplicated) and fstype (xfs\ext4). + 2. Configure the storage class - to define the storage system pool name, secret reference, `SpaceEfficiency`, and `fstype`. #### 1. Create an array secret Create a secret file as follows `array-secret.yaml` and update the relevant credentials: @@ -167,14 +242,14 @@ Create a secret file as follows `array-secret.yaml` and update the relevant cred kind: Secret apiVersion: v1 metadata: - name: - namespace: kube-system + name: + namespace: type: Opaque stringData: - management_address: # Array management addresses - username: # Array username + management_address: # Array management addresses + username: # Array username data: - password: # Array password + password: # Array password ``` Apply the secret: @@ -183,9 +258,26 @@ Apply the secret: $ kubectl apply -f array-secret.yaml ``` +To create the secret using a command line terminal, use the following command: +```bash +kubectl create secret generic --from-literal=username= --fromliteral=password= --from-literal=management_address= -n +``` + #### 2. Create storage classes -Create a storage class `storageclass-gold.yaml` file as follows, with the relevant capabilities, pool and, array secret: +Create a storage class `storageclass-gold.yaml` file as follows, with the relevant capabilities, pool and, array secret. + +Use the `SpaceEfficiency` parameters for each storage system. These values are not case sensitive: +* IBM FlashSystem A9000 and A9000R + * Always includes deduplication and compression. + No need to specify during configuration. +* IBM Spectrum Virtualize Family + * `thin` + * `compressed` + * `deduplicated` +* IBM DS8000 Family + * `standard` (default value, if not specified) + * `thin` ``` kind: StorageClass @@ -194,8 +286,8 @@ metadata: name: gold provisioner: block.csi.ibm.com parameters: - #SpaceEfficiency: # Optional: Values applicable for Storwize are: thin, compressed, or deduplicated - pool: + #SpaceEfficiency: # Optional: Values applicable for Spectrum Virtualize Family are: thin, compressed, or deduplicated + pool: # DS8000 Family paramater is VALUE_POOL_ID csi.storage.k8s.io/provisioner-secret-name: csi.storage.k8s.io/provisioner-secret-namespace: @@ -203,9 +295,10 @@ parameters: csi.storage.k8s.io/controller-publish-secret-namespace: csi.storage.k8s.io/fstype: xfs # Optional: Values ext4/xfs. The default is ext4. + volume_name_prefix: # Optional: DS8000 Family maximum prefix length is 5 characters. Maximum prefix length for other systems is 20 characters. ``` -Apply the storage class: +#### 3. Apply the storage class: ```bash $ kubectl apply -f storageclass-gold.yaml @@ -228,6 +321,9 @@ storageclass.storage.k8s.io/gold created

+## Upgrading + +In order to upgrade the CSI operator and driver from a previous version, uninstall the existing driver and then install the newer version. ## Uninstalling @@ -247,7 +343,7 @@ $ kubectl delete -f ibm-block-csi-operator.yaml ## Licensing -Copyright 2019 IBM Corp. +Copyright 2020 IBM Corp. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/build/Dockerfile.operator b/build/Dockerfile.operator index 3ba747bd2..3f462972c 100644 --- a/build/Dockerfile.operator +++ b/build/Dockerfile.operator @@ -27,11 +27,14 @@ RUN CGO_ENABLED=1 GOOS=linux go build \ FROM registry.access.redhat.com/ubi7/ubi-minimal:7.7-138 MAINTAINER IBM Storage +ARG VERSION=1.1.0 +ARG BUILD_NUMBER=0 + ###Required Labels LABEL name="Operator for IBM block storage CSI driver" \ vendor="IBM" \ - version="1.0.0" \ - release="b16" \ + version=$VERSION \ + release=$BUILD_NUMBER \ summary="The operator for IBM block storage CSI driver" \ description="The IBM block storage CSI driver enables container orchestrators, such as Kubernetes and OpenShift, to manage the life-cycle of persistent storage." \ io.k8s.display-name="Operator for IBM block storage CSI driver" \ diff --git a/build/bin/entrypoint b/build/bin/entrypoint index 3193408f8..457186bd8 100755 --- a/build/bin/entrypoint +++ b/build/bin/entrypoint @@ -1,12 +1,3 @@ #!/bin/sh -e -# This is documented here: -# https://docs.openshift.com/container-platform/3.11/creating_images/guidelines.html#openshift-specific-guidelines - -if ! whoami &>/dev/null; then - if [ -w /etc/passwd ]; then - echo "${USER_NAME:-ibm-block-csi-operator}:x:$(id -u):$(id -g):${USER_NAME:-ibm-block-csi-operator} user:${HOME}:/sbin/nologin" >> /etc/passwd - fi -fi - exec ${OPERATOR} $@ diff --git a/build/bin/user_setup b/build/bin/user_setup index 1e36064cb..fe1231363 100755 --- a/build/bin/user_setup +++ b/build/bin/user_setup @@ -2,12 +2,10 @@ set -x # ensure $HOME exists and is accessible by group 0 (we don't know what the runtime UID will be) +echo "${USER_NAME}:x:${USER_UID}:0:${USER_NAME} user:${HOME}:/sbin/nologin" >> /etc/passwd mkdir -p ${HOME} chown ${USER_UID}:0 ${HOME} chmod ug+rwx ${HOME} -# runtime user will need to be able to self-insert in /etc/passwd -chmod g+rw /etc/passwd - # no need for this script to remain in the image after running rm $0 diff --git a/build/ci/Dockerfile.unittest b/build/ci/Dockerfile.unittest index 2ba22ed64..f77f5f0f9 100644 --- a/build/ci/Dockerfile.unittest +++ b/build/ci/Dockerfile.unittest @@ -12,12 +12,22 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.12.6 +FROM golang:1.13.1 WORKDIR /go/src/github.com/IBM/ibm-block-csi-operator -# ENV GO111MODULE=on +ENV GO111MODULE=on \ + GOROOT=/usr/local/go RUN go get github.com/onsi/ginkgo/ginkgo +RUN RELEASE_VERSION=v0.16.0 \ + && ARCH=$(uname -m) \ + && SDK_ASSET=operator-sdk-${RELEASE_VERSION}-${ARCH}-linux-gnu \ + && curl -LO https://github.com/operator-framework/operator-sdk/releases/download/${RELEASE_VERSION}/${SDK_ASSET} \ + && chmod +x ${SDK_ASSET} \ + && mkdir -p /usr/local/bin/ \ + && cp ${SDK_ASSET} /usr/local/bin/operator-sdk \ + && rm ${SDK_ASSET} + COPY . . CMD ["make", "test"] \ No newline at end of file diff --git a/build/ci/build_image.sh b/build/ci/build_push_image.sh similarity index 90% rename from build/ci/build_image.sh rename to build/ci/build_push_image.sh index e14b5cb03..9fe59b9f5 100755 --- a/build/ci/build_image.sh +++ b/build/ci/build_push_image.sh @@ -1,12 +1,11 @@ #!/bin/bash -xe # Validations -MANDATORY_ENVS="IMAGE_VERSION BUILD_NUMBER DOCKER_REGISTRY GIT_BRANCH" +MANDATORY_ENVS="IMAGE_VERSION BUILD_NUMBER DOCKER_REGISTRY OPERATOR_IMAGE GIT_BRANCH" for envi in $MANDATORY_ENVS; do [ -z "${!envi}" ] && { echo "Error - Env $envi is mandatory for the script."; exit 1; } || : done -OPERATOR_IMAGE=ibm-block-csi-operator NODE_IMAGE=ibm-node-agent # Prepare specific tag for the image @@ -25,7 +24,7 @@ operator_tag_latest=${operator_registry}:latest [ "$tag_latest" = "true" ] && taglatestflag="-t ${operator_tag_latest}" echo "Build and push the Operator image" -docker build -t ${operator_tag_specific} $taglatestflag -f build/Dockerfile.operator . +docker build -t ${operator_tag_specific} $taglatestflag -f build/Dockerfile.operator --build-arg VERSION="${IMAGE_VERSION}" --build-arg BUILD_NUMBER="${BUILD_NUMBER}" . docker push ${operator_tag_specific} [ "$tag_latest" = "true" ] && docker push ${operator_tag_latest} || : diff --git a/build/ci/jenkins_pipeline_build b/build/ci/jenkins_pipeline_build index 06bccdfdc..cac1bad38 100644 --- a/build/ci/jenkins_pipeline_build +++ b/build/ci/jenkins_pipeline_build @@ -11,7 +11,7 @@ pipeline { } stage ('Build and push images') { steps { - sh './build/ci/build_image.sh build/_output/reports/images_url' + sh './build/ci/build_push_image.sh build/_output/reports/images_url' } } } diff --git a/deploy/crds/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/deploy/crds/csi.ibm.com_v1_ibmblockcsi_cr.yaml index 6d22984a6..38406a6e5 100644 --- a/deploy/crds/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/deploy/crds/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -12,7 +12,7 @@ spec: # container and csi-provisioner, csi-attacher and livenessprobe sidecars. controller: repository: ibmcom/ibm-block-csi-driver-controller - tag: "1.0.0" + tag: "1.1.0" imagePullPolicy: IfNotPresent affinity: nodeAffinity: @@ -28,7 +28,7 @@ spec: # and csi-node-driver-registrar and livenessprobe sidecars. node: repository: ibmcom/ibm-block-csi-driver-node - tag: "1.0.0" + tag: "1.1.0" imagePullPolicy: IfNotPresent affinity: nodeAffinity: @@ -52,7 +52,7 @@ spec: imagePullPolicy: IfNotPresent - name: csi-provisioner repository: quay.io/k8scsi/csi-provisioner - tag: "v1.3.0" + tag: "v1.4.0" imagePullPolicy: IfNotPresent - name: csi-attacher repository: quay.io/k8scsi/csi-attacher diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index 641cea2c9..ed1c5606c 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -1,4 +1,4 @@ -# Code generated by update-copyright.sh. DO NOT EDIT. +# Code generated by update-installer.sh. DO NOT EDIT. apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition @@ -1425,7 +1425,7 @@ spec: annotations: productName: ibm-block-csi-operator productID: ibm-block-csi-operator - productVersion: "1.0.0" + productVersion: "1.1.0" spec: serviceAccountName: ibm-block-csi-operator affinity: @@ -1460,7 +1460,7 @@ spec: capabilities: drop: - ALL - image: ibmcom/ibm-block-csi-operator:1.0.0 + image: ibmcom/ibm-block-csi-operator:1.1.0 imagePullPolicy: IfNotPresent command: - ibm-block-csi-operator @@ -1529,6 +1529,7 @@ rules: - update - create - delete + - patch - apiGroups: - "" resources: @@ -1586,6 +1587,7 @@ rules: - list - watch - update + - patch - apiGroups: - storage.k8s.io resources: @@ -1627,6 +1629,15 @@ rules: - get - list - watch +- apiGroups: + - security.openshift.io + resourceNames: + - anyuid + - privileged + resources: + - securitycontextconstraints + verbs: + - use - apiGroups: - apiextensions.k8s.io resources: diff --git a/deploy/olm-catalog/ibm-block-csi-operator/1.0.0/ibm-block-csi-operator.v1.0.0.clusterserviceversion.yaml b/deploy/olm-catalog/ibm-block-csi-operator/1.0.0/ibm-block-csi-operator.v1.0.0.clusterserviceversion.yaml index 24492e5d5..588792569 100644 --- a/deploy/olm-catalog/ibm-block-csi-operator/1.0.0/ibm-block-csi-operator.v1.0.0.clusterserviceversion.yaml +++ b/deploy/olm-catalog/ibm-block-csi-operator/1.0.0/ibm-block-csi-operator.v1.0.0.clusterserviceversion.yaml @@ -8,7 +8,7 @@ metadata: categories: "Storage,Cloud Provider" certified: "true" containerImage: registry.connect.redhat.com/ibm/ibm-block-csi-operator:1.0.0 - createdAt: "2019-11-05T16:45:00Z" + createdAt: "2019-11-19T13:14:00Z" description: "Run IBM block storage CSI driver on OpenShift." repository: https://github.com/IBM/ibm-block-csi-operator support: IBM @@ -291,12 +291,6 @@ spec: - kind: ServiceAccount name: '' version: v1 - - kind: ClusterRole - name: '' - version: rbac.authorization.k8s.io/v1beta1 - - kind: ClusterRoleBinding - name: '' - version: rbac.authorization.k8s.io/v1beta1 - kind: StatefulSet name: '' version: apps/v1 @@ -488,6 +482,15 @@ spec: - get - list - watch + - apiGroups: + - security.openshift.io + resourceNames: + - anyuid + - privileged + resources: + - securitycontextconstraints + verbs: + - use - apiGroups: - apiextensions.k8s.io resources: diff --git a/deploy/olm-catalog/ibm-block-csi-operator/1.1.0/csi.ibm.com_ibmblockcsis_crd.yaml b/deploy/olm-catalog/ibm-block-csi-operator/1.1.0/csi.ibm.com_ibmblockcsis_crd.yaml new file mode 100644 index 000000000..91ee190f3 --- /dev/null +++ b/deploy/olm-catalog/ibm-block-csi-operator/1.1.0/csi.ibm.com_ibmblockcsis_crd.yaml @@ -0,0 +1,1396 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: ibmblockcsis.csi.ibm.com +spec: + group: csi.ibm.com + names: + kind: IBMBlockCSI + listKind: IBMBlockCSIList + plural: ibmblockcsis + shortNames: + - ibc + singular: ibmblockcsi + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + description: IBMBlockCSI is the Schema for the ibmblockcsis API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: IBMBlockCSISpec defines the desired state of IBMBlockCSI + properties: + controller: + description: IBMBlockCSIControllerSpec defines the desired state of + IBMBlockCSIController + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling requirements + (resource request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if the node + matches the corresponding matchExpressions; the node(s) + with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values + array must be empty. If the operator is + Gt or Lt, the values array must have a + single element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values + array must be empty. If the operator is + Gt or Lt, the values array must have a + single element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not + be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its + node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. + The TopologySelectorTerm type implements a subset + of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values + array must be empty. If the operator is + Gt or Lt, the values array must have a + single element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values + array must be empty. If the operator is + Gt or Lt, the values array must have a + single element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling requirements + (resource request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if the node + has pods which matches the corresponding podAffinityTerm; + the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified + namespaces, where co-located is defined as running + on a node whose value of the label with key + topologyKey matches that of any node on which + any of the selected pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not + be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm are + intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located is + defined as running on a node whose value of the label + with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If + the operator is Exists or DoesNotExist, + the values array must be empty. This array + is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey matches + that of any node on which any of the selected pods + is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling requirements + (resource request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to the + sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified + namespaces, where co-located is defined as running + on a node whose value of the label with key + topologyKey matches that of any node on which + any of the selected pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met at + some point during pod execution (e.g. due to a pod label + update), the system may or may not try to eventually evict + the pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located is + defined as running on a node whose value of the label + with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If + the operator is Exists or DoesNotExist, + the values array must be empty. This array + is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey matches + that of any node on which any of the selected pods + is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull a + container image + type: string + repository: + type: string + tag: + type: string + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using the + matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to + Equal. Exists is equivalent to wildcard for value, so that + a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do + not evict). Zero and negative values will be treated as + 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - repository + - tag + type: object + imagePullSecrets: + items: + type: string + type: array + node: + description: IBMBlockCSINodeSpec defines the desired state of IBMBlockCSINode + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling requirements + (resource request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if the node + matches the corresponding matchExpressions; the node(s) + with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values + array must be empty. If the operator is + Gt or Lt, the values array must have a + single element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values + array must be empty. If the operator is + Gt or Lt, the values array must have a + single element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not + be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its + node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. + The TopologySelectorTerm type implements a subset + of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values + array must be empty. If the operator is + Gt or Lt, the values array must have a + single element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values + array must be empty. If the operator is + Gt or Lt, the values array must have a + single element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling requirements + (resource request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if the node + has pods which matches the corresponding podAffinityTerm; + the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified + namespaces, where co-located is defined as running + on a node whose value of the label with key + topologyKey matches that of any node on which + any of the selected pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not + be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm are + intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located is + defined as running on a node whose value of the label + with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If + the operator is Exists or DoesNotExist, + the values array must be empty. This array + is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey matches + that of any node on which any of the selected pods + is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling requirements + (resource request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to the + sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified + namespaces, where co-located is defined as running + on a node whose value of the label with key + topologyKey matches that of any node on which + any of the selected pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met at + some point during pod execution (e.g. due to a pod label + update), the system may or may not try to eventually evict + the pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located is + defined as running on a node whose value of the label + with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If + the operator is Exists or DoesNotExist, + the values array must be empty. This array + is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey matches + that of any node on which any of the selected pods + is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull a + container image + type: string + repository: + type: string + tag: + type: string + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using the + matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to + Equal. Exists is equivalent to wildcard for value, so that + a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do + not evict). Zero and negative values will be treated as + 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - repository + - tag + type: object + sidecars: + items: + properties: + imagePullPolicy: + description: The pullPolicy of the csi sidecar image + type: string + name: + description: The name of the csi sidecar image + type: string + repository: + description: The repository of the csi sidecar image + type: string + tag: + description: The tag of the csi sidecar image + type: string + required: + - name + - repository + - tag + type: object + type: array + required: + - controller + - node + type: object + status: + description: IBMBlockCSIStatus defines the observed state of IBMBlockCSI + properties: + controllerReady: + type: boolean + nodeReady: + type: boolean + phase: + description: Phase is the driver running phase + type: string + version: + description: Version is the current driver version + type: string + required: + - controllerReady + - nodeReady + - phase + - version + type: object + type: object + version: v1 + versions: + - name: v1 + served: true + storage: true diff --git a/deploy/olm-catalog/ibm-block-csi-operator/1.1.0/ibm-block-csi-operator.v1.1.0.clusterserviceversion.yaml b/deploy/olm-catalog/ibm-block-csi-operator/1.1.0/ibm-block-csi-operator.v1.1.0.clusterserviceversion.yaml new file mode 100644 index 000000000..0e6ec6042 --- /dev/null +++ b/deploy/olm-catalog/ibm-block-csi-operator/1.1.0/ibm-block-csi-operator.v1.1.0.clusterserviceversion.yaml @@ -0,0 +1,630 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + name: ibm-block-csi-operator.v1.1.0 + namespace: placeholder + annotations: + capabilities: "Basic Install" + categories: "Storage,Cloud Provider" + certified: "true" + containerImage: registry.connect.redhat.com/ibm/ibm-block-csi-operator:1.1.0 + createdAt: "2020-02-19T13:14:00Z" + description: "Run IBM block storage CSI driver on OpenShift." + repository: https://github.com/IBM/ibm-block-csi-operator + support: IBM + alm-examples: >- + [ + { + "apiVersion": "csi.ibm.com/v1", + "kind": "IBMBlockCSI", + "metadata": { + "name": "ibm-block-csi" + }, + "spec": { + "controller": { + "repository": "ibmcom/ibm-block-csi-driver-controller", + "tag": "1.1.0", + "imagePullPolicy": "IfNotPresent", + "affinity": { + "nodeAffinity": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "nodeSelectorTerms": [ + { + "matchExpressions": [ + { + "key": "kubernetes.io/arch", + "operator": "In", + "values": [ + "amd64" + ] + } + ] + } + ] + } + } + } + }, + "node": { + "repository": "ibmcom/ibm-block-csi-driver-node", + "tag": "1.1.0", + "imagePullPolicy": "IfNotPresent", + "affinity": { + "nodeAffinity": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "nodeSelectorTerms": [ + { + "matchExpressions": [ + { + "key": "kubernetes.io/arch", + "operator": "In", + "values": [ + "amd64" + ] + } + ] + } + ] + } + } + } + }, + "sidecars": [ + { + "name": "csi-node-driver-registrar", + "repository": "quay.io/k8scsi/csi-node-driver-registrar", + "tag": "v1.2.0", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "csi-provisioner", + "repository": "quay.io/k8scsi/csi-provisioner", + "tag": "v1.3.0", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "csi-attacher", + "repository": "quay.io/k8scsi/csi-attacher", + "tag": "v1.2.1", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "livenessprobe", + "repository": "quay.io/k8scsi/livenessprobe", + "tag": "v1.1.0", + "imagePullPolicy": "IfNotPresent" + } + ] + } + } + ] +spec: + displayName: "Operator for IBM block storage CSI driver" + description: | + **IBM block storage CSI driver** is a Container Storage Interface (CSI) Driver for IBM block storage systems which enables container orchestrators to manage the life cycle of persistent storage. + + This is the official operator to deploy and manage IBM block storage CSI driver. + + Supported container platforms: + - OpenShift v4.2 + - OpenShift v4.3 + - Kubernetes v1.14 + - Kubernetes v1.16 + + Supported IBM storage systems: + - IBM FlashSystem 9100 + - IBM Spectrum Virtualize Family (including IBM Flash family members built with IBM Spectrum Virtualize (FlashSystem 5010, 5030, 5100, 7200, 9100, 9200, 9200R) and IBM SAN Volume Controller (SVC) models SV2, SA2) + - IBM FlashSystem A9000/R + - IBM DS8880 + - IBM DS8900 + + Supported operating systems: + - RHEL 7.x (x86 architecture) + - RHCOS (x86 and IBM Z architecture) + + Full documentation can be found on the [IBM Knowledge Center](https://www.ibm.com/support/knowledgecenter/SSRQ8T). + + ## Prerequisites + + ### Preparing worker nodes + Perform these steps for each worker node: + + #### 1. Perform this step to ensure iSCSI connectivity, when using RHEL OS. + If using RHCOS or if the packages are already installed, continue to the next step. + + RHEL 7.x: + ```bash + yum -y install iscsi-initiator-utils # Only if iSCSI connectivity is required + yum -y install xfsprogs # Only if XFS file system is required + ``` + + #### 2. Configure Linux multipath devices on the host, using one of the following procedures. + The following yaml file example is for both Fibre Channel and iSCSI configurations. To support iSCSI, uncomment the last two lines in the file: + + **Important:** The `99-ibm-attach.yaml` configuration file overrides any files that already exist on your system. Only use this file if the files mentioned in the yaml below are not already created. If one or more have been created, edit this yaml file, as necessary. + + Save the `99-ibm-attach.yaml` file. + + ```bash + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfig + metadata: + labels: + machineconfiguration.openshift.io/role: worker + name: 99-ibm-attach + spec: + config: + ignition: + version: 2.2.0 + storage: + files: + - path: /etc/multipath.conf + mode: 384 + filesystem: root + contents: + source: data:,defaults%20%7B%0A%20%20%20%20path_checker%20tur%0A%20%20%20%20path_selector + %20%22round-robin%200%22%0A%20%20%20%20rr_weight%20uniform%0A%20%20%20%20prio%20const%0A + %20%20%20%20rr_min_io_rq%201%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20polling_interval + %2030%0A%20%20%20%20path_grouping_policy%20multibus%0A%20%20%20%20find_multipaths%20yes%0A + %20%20%20%20no_path_retry%20fail%0A%20%20%20%20user_friendly_names%20yes%0A%20%20%20%20failback + %20immediate%0A%20%20%20%20checker_timeout%2010%0A%20%20%20%20fast_io_fail_tmo%20off%0A%7D%0A%0Adevices + %20%7B%0A%20%20%20%20device%20%7B%0A%20%20%20%20%20%20%20%20path_checker%20tur%0A + %20%20%20%20%20%20%20%20product%20%22FlashSystem%22%0A%20%20%20%20%20%20%20%20vendor%20%22IBM%22%0A + %20%20%20%20%20%20%20%20rr_weight%20uniform%0A%20%20%20%20%20%20%20%20rr_min_io_rq + %204%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20path_grouping_policy + %20multibus%0A%20%20%20%20%20%20%20%20path_selector%20%22round-robin%200%22%0A + %20%20%20%20%20%20%20%20no_path_retry%20fail%0A%20%20%20%20%20%20%20%20failback%20immediate%0A + %20%20%20%20%7D%0A%20%20%20%20device%20%7B%0A%20%20%20%20%20%20%20%20path_checker%20tur%0A + %20%20%20%20%20%20%20%20product%20%22FlashSystem-9840%22%0A%20%20%20%20%20%20%20%20vendor%20%22IBM%22%0A + %20%20%20%20%20%20%20%20fast_io_fail_tmo%20off%0A%20%20%20%20%20%20%20%20rr_weight%20uniform%0A + %20%20%20%20%20%20%20%20rr_min_io_rq%201000%20%20%20%20%20%20%20%20%20%20%20%20%0A + %20%20%20%20%20%20%20%20path_grouping_policy%20multibus%0A%20%20%20%20%20%20%20%20path_selector + %20%22round-robin%200%22%0A%20%20%20%20%20%20%20%20no_path_retry%20fail%0A + %20%20%20%20%20%20%20%20failback%20immediate%0A%20%20%20%20%7D%0A%20%20%20%20device%20%7B%0A + %20%20%20%20%20%20%20%20vendor%20%22IBM%22%0A%20%20%20%20%20%20%20%20product%20%222145%22%0A + %20%20%20%20%20%20%20%20path_checker%20tur%0A%20%20%20%20%20%20%20%20features%20%221%20queue_if_no_path + %22%0A%20%20%20%20%20%20%20%20path_grouping_policy%20group_by_prio%0A + %20%20%20%20%20%20%20%20path_selector%20%22service-time%200%22%20%23%20Used%20by%20Red%20Hat%207.x%0A + %20%20%20%20%20%20%20%20prio%20alua%0A%20%20%20%20%20%20%20%20rr_min_io_rq%201%0A + %20%20%20%20%20%20%20%20rr_weight%20uniform%20%0A%20%20%20%20%20%20%20%20no_path_retry%20%225%22%0A + %20%20%20%20%20%20%20%20dev_loss_tmo%20120%0A%20%20%20%20%20%20%20%20failback%20immediate%0A%20%20%20%7D + %0A%7D%0A + verification: {} + - path: /etc/udev/rules.d/99-ibm-2145.rules + mode: 420 + filesystem: root + contents: + source: data:,%23%20Set%20SCSI%20command%20timeout%20to%20120s%20%28default%20%3D%3D + %2030%20or%2060%29%20for%20IBM%202145%20devices%0ASUBSYSTEM%3D%3D%22block%22%2C%20ACTION%3D%3D%22add + %22%2C%20ENV%7BID_VENDOR%7D%3D%3D%22IBM%22%2CENV%7BID_MODEL%7D%3D%3D%222145%22%2C%20RUN%2B%3D%22/bin/sh + %20-c%20%27echo%20120%20%3E/sys/block/%25k/device/timeout%27%22%0A + verification: {} + systemd: + units: + - name: multipathd.service + enabled: true + # Uncomment the following lines if this MachineConfig will be used with iSCSI connectivity + #- name: iscsid.service + # enabled: true + ``` + + Apply the yaml file. + ```bash + oc apply -f 99-ibm-attach.yaml + ``` + + RHEL users should verify that the `systemctl status multipathd` output indicates that the multipath status is active and error-free. + + ```bash + yum install device-mapper-multipath + modprobe dm-multipath + systemctl enable multipathd + systemctl start multipathd + systemctl status multipathd + multipath -ll + ``` + + #### 3. Configure storage system connectivity + 3.1. Define the hostname of each Kubernetes node on the relevant storage systems with the valid WWPN(for Fibre Channel) or IQN(for iSCSI) of the node. + + 3.2. For Fibre Channel, configure the relevant zoning from the storage to the host. + + ## Configuring k8s secret and storage class + In order to use the driver, create the relevant storage classes and secrets, as needed. + Note: This section can be done also after the operator installation. + + This section describes how to: + 1. Create a storage system secret - to define the storage system credentials (user and password) and its address. + 2. Configure the k8s storage class - to define the storage system pool name, secret reference, SpaceEfficiency (thin, compressed, or deduplicated) and fstype (xfs\ext4). + + #### 1. Create an array secret + Create a secret file as follows `array-secret.yaml` and update the relevant credentials: + + ``` + kind: Secret + apiVersion: v1 + metadata: + name: + namespace: + type: Opaque + stringData: + management_address: # Array management addresses + username: # Array username + data: + password: # Array password + ``` + + Apply the secret: + + ``` + $ kubectl apply -f array-secret.yaml + ``` + + To create the secret using a command line terminal, use the following command: + ```bash + kubectl create secret generic --from-literal=username= --fromliteral=password= --from-literal=management_address= -n + ``` + + #### 2. Create storage classes + + Create a storage class `storageclass-gold.yaml` file as follows, with the relevant capabilities, pool and, array secret. + + Use the `SpaceEfficiency` parameters for each storage system. These values are not case sensitive: + * IBM FlashSystem A9000 and A9000R + * Always includes deduplication and compression. No need to specify during configuration. + * IBM Spectrum Virtualize Family + * `thin` + * `compressed` + * `deduplicated` + * IBM DS8000 Family + * `standard` (default value, if not specified) + * `thin` + + ``` + kind: StorageClass + apiVersion: storage.k8s.io/v1 + metadata: + name: gold + provisioner: block.csi.ibm.com + parameters: + #SpaceEfficiency: # Optional: Values applicable for Spectrum Virtualize Family are: thin, compressed, or deduplicated + pool: # DS8000 Family paramater is VALUE_POOL_ID + + csi.storage.k8s.io/provisioner-secret-name: + csi.storage.k8s.io/provisioner-secret-namespace: + csi.storage.k8s.io/controller-publish-secret-name: + csi.storage.k8s.io/controller-publish-secret-namespace: + + csi.storage.k8s.io/fstype: xfs # Optional: Values ext4/xfs. The default is ext4. + volume_name_prefix: # Optional: DS8000 Family maximum prefix length is 5 characters. Maximum prefix length for other systems is 20 characters. + ``` + + #### 3. Apply the storage class: + + ```bash + $ kubectl apply -f storageclass-gold.yaml + storageclass.storage.k8s.io/gold created + ``` + + keywords: + - IBM + - BlockStorage + - CSI + version: 1.1.0 + replaces: ibm-block-csi-operator.v1.0.0 + maturity: stable + maintainers: + - name: Guang Jiong Lou + email: luogj@cn.ibm.com + minKubeVersion: 1.14.1 + provider: + name: IBM + links: + - name: Source Code + url: https://github.com/IBM/ibm-block-csi-operator + icon: + - base64data: iVBORw0KGgoAAAANSUhEUgAAEXAAAAeYCAYAAACWKEghAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjQxRDU4ODQ3NDFDRTExRTY4NzAxOTUyQjlGMzgxMjIxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjQxRDU4ODQ4NDFDRTExRTY4NzAxOTUyQjlGMzgxMjIxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NDFENTg4NDU0MUNFMTFFNjg3MDE5NTJCOUYzODEyMjEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NDFENTg4NDY0MUNFMTFFNjg3MDE5NTJCOUYzODEyMjEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5Sn3ZJAADIZUlEQVR42uzdXXIbNxqGUdrlfSArmUZ2hKyA8ApGO2IjKxmthNNtk7HyI0f+TIoN9DlVkCgnF6k3F82mqYcfzufzAQAAAAAAAAAAAAAAAAAAAACAH/fRBAAAAAAAAAAAAAAAAAAAAAAAMQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAAAAAAAAAAAAAAAEECLgAAAAAAAAAAAAAAAAAAAAAAQQIuAAAAAAAAAAAAAAAAAAAAAABBAi4AAAAAAAAA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AAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAAAAAAAAAAAAAAAABIEnABAAAAAAAAAAAAAAAAAAAAAEgScAEAAAAAAAAAAAAAAAAAAAAASBJwAQAAAAAA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DLgAAAAAAAAAAAAAAAAAAAAAAAQZcAEAAAAAAAAAAAAAAAAAAAAACDLgAgAAAAAAAAAAAAAAAAAAAAAQZMAFAAAAAAAAAAAAAAAAAAAAACDIgAsAAAAAAAAAAAAAAAAAAAAAQJABFwAAAAAAAAAAAAAAAAAAAACAIAMuAAAAAAAAAAAAAAAAAAAAAABBBlwAAAAAAAAAAAAAAAAAAAAAAIIMuAAAAAAAAAAAAAAAAAAAAAAABBlwAQAAAAAAAAAAAAAAAAAAAAAIMuACAAAAAAAAAAAAAAAAAAAAABBkwAUAAAAAAAAAAAAAAAAAAAAAIMiACwAAAAAAAAAAAAAAAAAAAABAkAEXAAAAAAAAAAAAAAAAAAAAAIAgAy4AAAAAAAAAAAAAAAAAAAAAAEEGXAAAAAAAAAAAAAAAAAAAAAAAggy4AAAAAAAAAAAAAAAAAAAAAAAEGXABAAAAAAAAAAAAAAAAAAAAAAgy4AIAAAAAAAAAAAAAAAAAAAAAEGTABQAAAAAAAAAAAAAAAAAAAAAgyIALAAAAAAAAAAAAAAAAAAAAAECQARcAAAAAAAAAAAAAAAAAAAAAgCADLgAAAAAAAAAAAAAAAAAAAAAAQQZcAAAAAAAAAAAAAAAAAAAAAACCDLgAAAAAAAAAAAAAAAAAAAAAAAQZcAEAAAAAAAAAAAAAAAAAAAAACDLgAgAAAAAAAAAAAAAAAAAAAAAQZMAFAAAAAAAAAAAAAAAAAAAAACDIgAsAAAAAAAAAAAAAAAAAAAAAQJABFwAAAAAAAAAAAAAAAAAAAACAIAMuAAAAAAAAAAAAAAAAAAAAAABBBlwAAAAAAAAAAAAAAAAAAAAAAIIMuAAAAAAAAAAAAAAAAAAAAAAABBlwAQAAAAAAAAAAAAAAAAAAAAAIMuACAAAAAAAAAAAAAAAAAAAAABBkwAUAAAAAAAAAAAAAAAAAAAAAIMiACwAAAAAAAAAAAAAAAAAAAABAkAEXAAAAAAAAAAAAAAAAAAAAAIAgAy4AAAAAAAAAAAAAAAAAAAAAAEEGXAAAAAAAAAAAAAAAAAAAAAAAggy4AAAAAAAAAAAAAAAAAAAAAAAEGXABAAAAAAAAAAAAAAAAAAAAAAgy4AIAAAAAAAAAAAAAAAAAAAAAEGTABQAAAAAAAAAAAAAAAAAAAAAgyIALAAAAAAAAAAAAAAAA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AACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAAAACAIAEXAAAAAAAAAAAAAAAAAAAAAIAgARcAAAAAAAAAAAAAAAAAAAAAgCABFwAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAABBkwAUAAAAAAAAAAAAAAAAAAAAAIMiACwAAAAAAAAAAAAAAAAAAAABAkAEXAAAAAAAAAAAAAAAAAAAAAIAgAy4AAAAAAAAAAAAAAAAAAAAAAEEGXAAAAAAAAAAAAAAAAAAAAAAAggy4AAAAAAAAAAAAAAAAAAAAAAAEGXABAAAAAAAAAAAAAAAAAAAAAAgy4AIAAAAAAAAAAAAAAAAAAAAAEGTABQAAAAAAAAAAAAAAAAAAAAAgyIALAAAAAAAAAAAAAAAAAAAAAECQARcAAAAAAAAAAAAAAAAAAAAAgCADLgAAAAAAAAAAAAAAAAAAAAAAQQZcAAAAAAAAAAAAAAAAAAAAAACCDLgAAAAAAAAAAAAAAAAAAAAAAAQZcAEAAAAAAAAAAAAAAAAAAAAACDLgAgAAAAAAAAAAAAAAAAAAAAAQZMAFAAAAAAAAAAAAAAAAAAAAACDIgAsAAAAAAAAAAAAAAAAAAAAAQJABFwAAAAAAAAAAAAAAAAAAAACAIAMuAAAAAAAAAAAAAAAAAAAAAABBBlwAAAAAAAAAAAAAAAAAAAAAAIIMuAAAAAAAAAAAAAAAAAAAAAAABBlwAQAAAAAAAAAAAAAAAAAAAAAIMuACAAAAAAAAAAAAAAAAAAAAABBkwAUAAAAAAAAAAAAAAAAAAAAAIMiACwAAAAAAAAAAAAAAAAAAAABAkAEXAAAAAAAAAAAAAAAAAAAAAIAgAy4AAAAAAAAAAAAAAAAAAAAAAEEGXAAAAAAAAAAAAAAAAAAAAAAAggy4AAAAAAAAAAAAAAAAAAAAAAAEGXABAAAAAAAAAAAAAAAAAAAAAAgy4AIAAAAAAAAAAAAAAAAAAAAAEGTABQAAAAAAAAAAAAAAAAAAAAAgyIALAAAAAAAAAAAAAAAAAAAAAECQARcAAAAAAAAAAAAAAAAAAAAAgCADLgAAAAAAAAAAAAAAAAAAAAAAQQZcAAAAAAAAAAAAAAAAAAAAAACCDLgAAAAAAAAAAAAAAAAAAAAAAAQZcAEAAAAAAAAAAAAAAAAAAAAACDLgAgAAAAAAAAAAAAAAAAAAAAAQZMAFAAAAAAAAAAAAAAAAAAAAACDIgAsAAAAAAAAAAAAAAAAAAAAAQJABFwAAAAAAAAAAAAAAAAAAAACAIAMuAAAAAAAAAAAAAAAAAAAAAABBBlwAAAAAAAAAAAAAAAAAAAAAAIIMuAAAAAAAAAAAAAAAAAAAAAAABBlwAQAAAAAAAAAAAAAAAAAAAAAIMuACAAAAAAAAAAAAAAAAAAAAABBkwAUAAAAAAAAAAAAAAAAAAAAAIMiACwAAAAAAAAAAAAAAAAAAAABAkAEXAAAAAAAAAAAAAAAAAAAAAIAgAy4AAAAAAAAAAAAAAAAAAAAAAEEGXAAAAAAAAAAAAAAAAAAAAAAAggy4AAAAAAAAAAAAAAAAAAAAAAAEGXABAAAAAAAAAAAAAAAAAAAAAAgy4AIAAAAAAAAAAAAAAAAAAAAAEGTABQAAAAAAAAAAAAAAAAAAAAAgyIALAAAAAAAAAAAAAAAAAAAAAECQARcAAAAAAAAAAAAAAAAAAAAAgCADLgAAAAAAAAAAAAAAAAAAAAAAQQZcAAAAAAAAAAAAAAAAAAAAAACCDLgAAAAAAAAAAAAAAAAAAAAAAAQZcAEAAAAAAAAAAAAAAAAAAAAACDLgAgAAAAAAAAAAAAAAAAAAAAAQZMAFAAAAAAAAAAAAAAAAAAAAACDIgAsAAAAAAAAAAAAAAAAAAAAAQJABFwAAAAAAAAAAAAAAAAAAAACAIAMuAAAAAAAAAAAAAAAAAAAAAABBBlwAAAAAAAAAAAAAAAAAAAAAAIK+SgCQx0+//n6vAsCna3/89nOXAQDwuROAj/rceT5tPncCXMHh2LfHX4oSAJ9/T/v4uto97eP98d9fPzw8qAss76dff3cfC3ADf/z2864CwWu3n6kCcE3t7orfW5v0vsy/AvchAKNfq3wPASARAy4AuVQJAG5y9nqQDgDwuRMAnzsBxlfc0wLcRHt8/SIDgPtYgMl4+Ioo120Arn1d8fNi3IcAjM33EAAS+SIBAAAAAAAAAABwI0UCAAAgkSoBAFfUJAAAABiHARcAAAAAAAAAAOCW7iUAAACS8D+vA3At7fHVZQAAABiHARcAAAAAAAAAAOCWyjX+kvNpUxIAAJhBkwAA1xMAAID1GHABAAAAAAAAAABuqUgAAAAk0iQA4Ap2CQAAAMZiwAUAAAAAAAAAALi1ewkAAIAkPHAPwHs1CQAAAMZjwAUAAAAAAAAAALi1IgEAAJBIkwAA1xEAAIC1GHABAAAAAAAAAABurUgAAAAkUiUA4B12CQAAAMZjwAUAAAAAAAAAABjBvQQAAEASXQIAgqoEAAAAYzLgAgAAAAAAAAAAjKBE/+D5tKkHAADMpkoAQECTAAAAYEwGXAAAAAAAAAAAgBEUCQAAgESaBAAEdAkAAADGZMAFAAAAAAAAAAAYxb0EAABAEh7AB+CtqgQAAADjMuACAAAAAAAAAAAAAADw+aoEALxBkwAAAGBcBlwAAAAAAAAAAIBRVAkAAIBEdgkAuFB7fHUZAAAAxmXABQAAAAAAAAAAGMkmAQAAkEiTAADXCwAAgPkZcAEAAAAAAAAAAEZS3vLm88neCwAAMLUmAQAX2CUAAAAYmwEXAAAAAAAAAABgJFUCAAAgEQ/kA/CaJgEAAMD4DLgAAAAAAAAAAACj2SQAAAASaRIA8ANVAgAAgPEZcAEAAAAAAAAAAEZTJAAAABJpEgDwA10CAACA8RlwAQAAAAAAAAAARlMkAAAAEtklAOAFVQIAAIA5GHABAAAAAAAAAABGUy550/m0KQUAAKyiSgDAM5oEAAAAczDgAgAAAAAAAAAAjOheAgAAIJEmAQDP6BIAAADMwYALAAAAAAAAAAAwoiIBAACQiAf0AfinKgEAAMA8DLgAAAAAAAAAAAAjKhIAAADJVAkAeGKXAAAAYB4GXAAAAAAAAAAAgFFtEgAAAIk0CQBwTQAAAJiTARcAAAAAAAAAAGBU5aXfOJ9suwAAAMvpdx7YB+BPrgcAAACTMeACAAAAAAAAAACMqkoAAAAk0yQA4NEuAQAAwFwMuAAAAAAAAAAAAAAAAIzBA/sANAkAAADmY8AFAAAAAAAAAAAY2b0EAABAMk0CgNSqBAAAAPMx4AIAAAAAAAAAAEzlfNpEAAAAVtYkAEitSwAAADAfAy4AAAAAAAAAAMDIqgQAAEAyuwQAaVUJAAAA5mTABQAAAAAAAAAAGN0mAQAAkEyVACClJgEAAMCcDLgAAAAAAAAAAACjKxIAAADJNAkAUuoSAAAAzMmACwAAAAAAAAAAMLry1xfn06YGAACQgQf4AfKpEgAAAMzLgAsAAAAAAAAAADC6IgEAAJBQlQAglV0CAACAeRlwAQAAAAAAAAAAZrBJAAAAJNMkAHDmAwAAMAcDLgAAAAAAAAAAwAyKBAAAQDJdAoA0mgQAAABzM+ACAAAAAAAAAADMoJxPmwoAAEA2VQKAFHYJAAAA5mbABQAAAAAAAAAAmEGRAAAASMgD/QDraxIAAADMz4ALAAAAAAAAAAAwhcOxbyoAAAAJNQkAllYlAAAAmJ8BFwAAAAAAAAAAYBZFAgAAIKEmAcDSugQAAADzM+ACAAAAAAAAAADMokgAAAAktEsAsKwqAQAAwBoMuAAAAAAAAAAAALMoEgAAAEk1CQCc7wAAAIzLgAsAAAAAAAAAADCNw7FvKgAAAAlVCQCW1CUAAABYgwEXAAAAAAAAAABgJkUCAAAgIQ/4A6ynSgAAALAOAy4AAAAAAAAAAMBMigQAAEBSVQKApewSAAAArMOACwAAAAAAAAAAMJMiAQAAkFSTAMCZDgAAwJgMuAAAAAAAAAAAAAAAAIyvSwCwjCYBAADAWgy4AAAAAAAAAAAAUzkc+70KAABAUlUCgCXsEgAAAKzFgAsAAAAAAAAAAAAAAMAcPPAPML8mAQAAwHoMuAAAAAAAAAAAALOpEgAAAIk1CQCmViUAAABYjwEXAAAAAAAAAAAAAACAeTQJAKbWJQAAAFiPARcAAAAAAAAAAGA6h2PfVAAAAJLaJQCYVpUAAABgTQZcAAAAAAAAAACAGRUJAACAxJoEAM5vAAAAxvFVAgAAAAAAgHkdjl0EAACyKnf+13kAACCvdmfYEmBGfsALAACwqC8SAAAAAAAAAAAAEyoSAAAAiRm0BJhPlQAAAGBdBlwAAAAAAAAAAAAAAADmUyUAmIrxLQAAgIUZcAEAAAAAAAAAAKZ0OPZ7FQAAgMSaBADObAAAAMZgwAUAAAAAAAAAAAAAAGA+XQKAaTQJAAAA1mbABQAAAAAAAAAAmFWRAAAASK5KADCFXQIAAIC1GXABAAAAAAAAAABmVSQAAACSaxIAOKsBAAC4PQMuAAAAAAAAAAAAAAAAc+p3hgEARlclAAAAWJ8BFwAAAAAAAAAAYFqHY79XAQAASK5JADC0LgEAAMD6DLgAAAAAAAAAAAAAAADMa5cAYFhVAgAAgBwMuAAAAAAAAAAAAAAAAMytSQDgfAYAAOB2DLgAAAAAAAAAAAAzqxIAAAAYCAAYVJcAAAAgBwMuAAAAAAAAAAAAAAAAc9slABhOlQAAACAPAy4AAAAAAAAAAMDUDse+qQAAAGAoAGAwxrUAAAASMeACAAAAAAAAAADMrkgAAABw1yQAcCYDAABwGwZcAAAAAAAAAAAAAAAA5tclABhGkwAAACAXAy4AAAAAAAAAAMDsigQAAADfVAkAhrBLAAAAkIsBFwAAAAAAAAAAYHZFAgAAgG+aBADOYgAAAD6fARcAAAAAAAAAAAAAAIA1dAkAbq5KAAAAkI8BFwAAAAAAAAAAYHqHY99UAAAA+KZKAHBTxrQAAAASMuACAAAAAAAAAACsoEgAAADwzS4BwM1UCQAAAHIy4AIAAAAAAAAAAAAAALCWJgGA8xcAAIDPY8AFAAAAAAAAAAAAAABgLU0CgJvoEgAAAOT0VQIAAAAAAAAAAGAB9fG1ywAAAKzufNouedt+OPaqFsCnqk/P6MdzWBEAAIBEvkgAAAAAAAAAAAAAAAAwhzcMAjS1AD7P+bTtgbMaAACARRhwAQAAAAAAAAAAAAAAWE+VAODTNAkAAAByM+ACAAAAAAAAAAAs4XDsmwoAAAB/Op+2rgLAp2kSAAAA5GbABQAAAAAAAAAAWEWRAAAAyOBwvHibpaoF8PHOp20PnNEAAAAsxIALAAAAAAAAAAAAAADAmpoEAM5aAAAAPp4BFwAAAAAAAAAAAAAAgAWdT1tXAeDDVQkAAAAw4AIAAAAAAAAAAKyiSAAAAGRxOF68zVLVAvg4T8ey3nA2AwAAsBgDLgAAAAAAAAAAwCqKBAAAAN87n7ZdBYAPUyUAAADgfwy4AAAAAAAAAAAAAAAArK1JAOB8BQAA4OMYcAEAAAAAAAAAAAAAAJjQ4dgvfWtTC+D6zqetB85kAAAAFmTABQAAAAAAAAAAWMbh2DcVAAAAvnc+bbsKAFdXJQAAAOAvBlwAAAAAAAAAAICVFAkAAACe1SQAuB7jWAAAADxlwAUAAAAAAAAAAAAAAGBSh2O/9K1NLYCracGzGAAAgEUZcAEAAAAAAAAAAAAAAFjc+bTtKgBcTZMAAACAp75KAAAAAAAAAAAAAAAAMK/DsV/61vr/FwDvs7/h7AUAACCBLxIAAAAAAAAAAAAAAACk0CQAcJYCAABwfQZcAAAAAAAAAACAlVQJAAAAXtQlAHi3KgEAAAD/ZMAFAAAAAAAAAAAAAAAgjyoBwLsYwwIAAOBfDLgAAAAAAAAAAAAAAADk0SQACKsSAAAA8BwDLgAAAAAAAAAAAAAAAHn0OyMuAFHOTwAAAJ5lwAUAAAAAAAAAAAAAACCXJgFASJcAAACA5xhwAQAAAAAAAAAAAAAAyGWXAODNqgQAAAC8xIALAAAAAAAAAACwlMOxbyoAAAC8qkkA8CbGrwAAAHiRARcAAAAAAAAAAGA1RQIAAIBXNQkAnJkAAABchwEXAAAAAAAAAAAAAACAfHYJAC7WJAAAAOBHDLgAAAAAAAAAAAAAAADkVCUAuIjRKwAAAH7IgAsAAAAAAAAAAAAAAEBOTQIAZyUAAADvZ8AFAAAAAAAAAAAAAAAgpy4BwKuqBAAAALzGgAsAAAAAAAAAAAAAAEBeVQKAHzJ2BQAAwKsMuAAAAAAAAAAAAAAAAOTVJAB4UZUAAACASxhwAQAAAAAAAAAAAAAAyKtLAPCiJgEAAACXMOACAAAAAAAAAAAAAACQW5UA4FlGrgAAALiIARcAAAAAAAAAAAAAAIDcdgkA/qVKAAAAwKUMuAAAAAAAAAAAAAAAANAkAPiOcSsAAAAuZsAFAAAAAAAAAAAAAACAJgGAMxEAAIAYAy4AAAAAAAAAAAAAAADsEgD8rUkAAADAW/zn4eFBBQAAAAAAAAAAAAAAAAAAAACAgC8SAAAAAAAAAAAAAAAAAAAAAADEGHABAAAAAAAAAAAAAAAAAAAAAAgy4AIAAAAAAAAAAAAAAAAAAAAAEGTABQAAAAAAAAAAAAAAAAAAAAAgyIALAAAAAAAAAAAAAAAAAAAAAECQARcAAAAAAAAAAAAAAAAAAAAAgCADLgAAAAAAAAAAAAAAAAAAAAAAQQZcAAAAAAAAAAAAAAAAAAAAAACCDLgAAAAAAAAAAAAAAAAAAAAAAAQZcAEAAAAAAAAAAAAAAAAAAAAACDLgAgAAAAAAAAAAAAAAAAAAAAAQZMAFAAAAAAAAAAAAAAAAAAAAACDIgAsAAAAAAAAAAAAAAAAAAAAAQJABFwAAAAAAAAAAAAAAAAAAAACAIAMuAAAAAAAAAAAAAAAAAAAAAABBBlwAAAAAAAAAAAAAAAAAAAAAAIIMuAAAAAAAAAAAAAAAAAAAAAAABBlwAQAAAAAAAAAAAAAAAAAAAAAIMuACAAAAAAAAAAAAAAAAAAAAABBkwAUAAAAAAAAAAAAAAAAAAAAAIMiACwAAAAAAAAAAAAAAAAAAAABAkAEXAAAAAAAAAAAAAAAAAAAAAIAgAy4AAAAAAAAAAAAAAAAAAAAAAEEGXAAAAAAAAAAAAAAAAAAAAAAAggy4AAAAAAAAAAAAAAAAAAAAAAAEGXABAAAAAAAAAAAAAAAAgP+yc8cCAAAAAIP8reewu0ACAACASeACAAAAAAAAAAAAAAAAAAAAADAJXAAAAAAAAAAAAAAAAAAAAAAAJoELAAAAAAAAAAAAAAAAAAAAAMAkcAEAAAAAAAAAAAAAAAAAAAAAmAQuAAAAAAAAAAAAAAAAAAAAAACTwAUAAAAAAAAAAAAAAAAAAAAAYBK4AAAAAAAAAAAAAAAAAAAAAABMAhcAAAAAAAAAAAAAAAAAAAAAgEngAgAAAAAAAAAAAAAAAAAAAAAwCVwAAAAAAAAAAAAAAAAAAAAAACaBCwAAAAAAAAAAAAAAAAAAAADAJHABAAAAAAAAAAAAAAAAAAAAAJgELgAAAAAAAAAAAAAAAAAAAAAAk8AFAAAAAAAAAAAAAAAAAAAAAGASuAAAAAAAAAAAAAAAAAAAAAAATAIXAAAAAAAAAAAAAAAAAAAAAIBJ4AIAAAAAAAAAAAAAAAAAAAAAMAlcAAAAAAAAAAAAAAAAAAAAAAAmgQsAAAAAAAAAAAAAAAAAAAAAwJQA7N2JjRvHFobR0WDyoCJx0xlREbzqCNQh3VYk6khkyguellnIO71UdZ8DEAYMyzJ+sTwsSvxGwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIEnABQAAAAAAAAAAAAAAAAAAAAAgScAFAAAAAAAAAAAAAAAAAAAAACBJwAUAAAAAAAAAAAAAAAAAAAAAIOnJBKzh46cv/7MCAABQoZiGbjRDG06Xsbv+5WwJAAAAADi2aeh6K6zndHnxbXTv2QIAh/X18x9ek5Ly8dMXI7yPzyWAr6tA/nWIr6MAAO4jLEzAhbUUEwAAAJXeVQRc2nF2vwQAAAAArvwhujqcH7xnCwB4TQqsfw85mwF8XQVSigkAANxHWNajCQAAAAAAAAAAAAAAAKhcmAB2p5gAAACAvRBwAQAAAAAAAAAAWlFMAAAAcFi+KzY41wAAAFAtARcAAAAAAAAAAAAAAABaECYA5xkAAABqJOACAAAAAAAAAAC0IkwAAADgXgg4zwAAAFAbARcAAAAAAAAAAKAJ09CNVgAAADi03gTgPAMAAECNBFwAAAAAAAAAAAAAAABoRTEBNC9MAAAAwN4IuAAAAAAAAAAAAC0oJgAAAOBB+AGcYwAAAKiQgAsAAAAAAAAAAAAAAACtGE0AzetNAAAAwN4IuAAAAAAAAAAAAC0IEwAAAPCvYgJoVpgAAACAPRJwAQAAAAAAAAAAqjcNne+wDgAAwH96E0CzwgQAAADskYALAAAAAAAAAAAAAAAArQkTQJMEmAAAANglARcAAAAAAAAAAKB2xQQAAAD8IkwAzi0AAADUQsAFAAAAAAAAAAAAAACA1vQmgOYUEwAAALBXAi4AAAAAAAAAAEDtwgQAAAA8o5gAmjKaAAAAgL0ScAEAAAAAAAAAAKo2DZ0P9wAAAPCcMAE0o5gAAACAPRNwAQAAAAAAAAAAahYmAAAA4AWCn9COMAEAAAB7JuACAAAAAAAAAADULEwAAADAK4oJoAmCSwAAAOyagAsAAAAAAAAAAAAAAACtChNA9YoJAAAA2DsBFwAAAAAAAAAAoFrT0PVWAAAA4BXjg4gL1M4ZBQAAYPcEXAAAAAAAAAAAAAAAAGhZmACqNpoAAACAvRNwAQAAAAAAAAAAahUmAAAA4Aa9CaBaxQQAAAAcgYALAAAAAAAAAABQqzABAAAA7pDgbAIAAEDtBFwAAAAAAAAAAIBahQkAAAC4UTEBVGk0AQAAAEcg4AIAAAAAAAAAAFRpGjof8AEAAOBW7pBQn2ICAAAAjkLABQAAAAAAAAAAqFGYAAAAgDsVE0BVehMAAABwFAIuAAAAAAAAAABAjcIEAAAAuEuC8wgAAAAtEHABAAAAAAAAAAAAAABgD8YH0QiohbMIAADAoQi4AAAAAAAAAAAA1ZmGrrcCAAAACWECqIL3dgAAADgUARcAAAAAAAAAAAAAAAD2QjQCthcmAAAA4GgEXAAAAAAAAAAAgNoUEwAAAPAOYQJwBgEAAGBNAi4AAAAAAAAAAAAAAADsSZgANtWbAAAAgKMRcAEAAAAAAAAAAKoyDZ0P+QAAAPAe7pWwnTABAAAARyTgAgAAAAAAAAAAAAAAwN4UE8AmwgQAAAAckYALAAAAAAAAAABQk2ICAAAAZhAmgE30JgAAAOCIBFwAAAAAAAAAAAAAAADYm9EEsLowAQAAAEcl4AIAAAAAAAAAAFRjGjrfpRkAAIC5FBOAMwcAAABrEHABAAAAAAAAAAAAAABgj0RCYV2jCQAAADgqARcAAAAAAAAAAKAWxQQAAADMLEwAqygmAAAA4MgEXAAAAAAAAAAAAAAAANirMAE4awAAALC0JxMAAAAAAAAAAAA1mIaut0J1vybP/v3TZTQOAADQiu93zWIGWJw3CwAAADi0RxMAAAAAAAAAAAAVCBMAAACwkGICcMYAAABgSQIuAAAAAAAAAABADcIEAAAAuHOCMwYAAAAtEnABAAAAAAAAAABqECYAAABgIaMJwBkDAACAJQm4AAAAAAAAAAAAm5uGzgd9AAAAWFIxAThbAAAAsBQBFwAAAAAAAAAAYGthAgAAANw9wdkCAACAVgm4AAAAAAAAAAAAWwsTAAAAsLDR/RMWO1sAAABweAIuAAAAAAAAAADA1sIEAAAAuH9Cc4oJAAAA4B8CLgAAAAAAAAAAwKamofOdmgEAAFhDbwKYVZgAAAAA/iHgAgAAAAAAAAAAbKmYAAAAgBWFCWC2syTKCwAAAP8ScAEAAAAAAAAAAAAAAOAoiglgFmECAAAA+D8BFwAAAAAAAAAAYDPT0PVWAAAAYEWjCWAW3tMBAACAHwi4AAAAAAAAAAAAWwkTAAAAsIFiAniXMAEAAAD8TMAFAAAAAAAAAADYSpgAAAAA91FwhgAAAKB1TyYAAAAAAAAAAAA20p8u4yL/4mnorAsAAMBLvl9G4/o4mwJSehMAAADAzx5NAAAAAAAAAAAAAAAAwMGECcDZAQAAgLkIuAAAAAAAAAAAAFsoJgAAAGBDvQkgJUwAAAAAvxNwAQAAAAAAAAAAthAmAAAAwN0UmiN+BAAAAM8QcAEAAAAAAAAAALYwmgAAAICNhQnAmQEAAIA5CLgAAAAAAAAAAABrKyYAAACgAr0J4C5hAgAAAHiegAsAAAAAAAAAALC2MAEAAACVKCaAm4keAQAAwAsEXAAAAAAAAAAAgLWNJgAAAKASYQK4STEBAAAAvEzABQAAAAAAAAAAWFOYAAAAgIqIjMJtwgQAAADwMgEXAAAAAAAAAABgTWECAAAAKlNMAG8SOwIAAIBXCLgAAAAAAAAAAABr6k0AAACAuyo0pZgAAAAAXifgAgAAAAAAAAAArCVMAAAAgDsrOB8AAACwNwIuAAAAAAAAAADAWsIEAAAAuLNCc0YTAAAAwOsEXAAAAAAAAAAAgLX0JgAAAMCdFZpSTAAAAABvE3ABAAAAAAAAAADWEGv9RNPQWRsAAICMYgL4TZgAAAAA3ibgAgAAAAAAAAAArCFMAAAAgLsrNGc0AQAAALxNwAUAAAAAAAAAAFhDbwIAAAAqJ1QBPysmAAAAgNsIuAAAAAAAAAAAAEsrJgAAAMAdFpoTJgAAAIDbCLgAAAAAAAAAAABLCxMAAADgDgvNnYXRDAAAAHAbARcAAAAAAAAAAGBpPuwDAABAS3fYMAM4BwAAAHAPARcAAAAAAAAAAGBJxQQAAAA0JkwAD70JAAAA4HYCLgAAAAAAAAAAwJLCBAAAADRGuIKjCxMAAADAfQRcAAAAAAAAAACApcT1MZoBAACARu+04PkPAAAA3OTJBAAAAAAAAAAAwELCBAAAANRgGrq7/vnTZSzutRz4vPS/nAejAAAAwBseTQAAAAAAAAAAACykNwEAAAAtmoZOsYKjChMAAADA/QRcAAAAAAAAAACAJRQTAAAA4G4LzQkTAAAAwP0EXAAAAAAAAAAAgCXEFj/pNHSWBwAA4Deny9jM3Ra2NA1dP8PZAQAAgMMRcAEAAAAAAAAAAOYW14dP9wAAANC0aejGBxEXjsXzHQAAAJIEXAAAAAAAAAAAgLmFCQAAAKjN6ZJqjbrjciSe7wAAAJAk4AIAAAAAAAAAAMytNwEAAAB7MA2dOy6Hfb4no0cAAABwSAIuAAAAAAAAAADAnIoJAAAA2JkwAQdQTAAAAAB5Ai4AAAAAAAAAAMCcwgQAAADU6nQZMz+sWI4DiBnOCgAAAByWgAsAAAAAAAAAADCXuD58ugcAAIBdmYbOXRfPcwAAAOBVAi4AAAAAAAAAAMBcigkAAABw5wXPbwAAADgaARcAAAAAAAAAAGAOcX1s+p2ap6HzqwAAAMCbTpfU9TUsx47FDGcEAAAADk3ABQAAAAAAAAAAmEOYAAAAgL2ahk7RAs9vAAAA4EUCLgAAAAAAAAAAwBx6EwAAALBzxQR4XgMAAADPeTIBAAAAAAAAAADwTsUEAAAAtOR0GTM/rHcHZocieR4AAACAHzyaAAAAAAAAAAAAeKfeBAAAABxEmICdUW8BAACAGTyZAAAAAAAAAAAAeIfy9fMfdfyXfP7mV2MlHz99MQIAANypmrsT770PxfUvZ0uwE8UEAAAAMI9HEwAAAAAAAAAAAO/QmwAAAAD3YGhSmAAAAADmIeACAAAAAAAAAABkFRMAAADgPgxNiutjNAMAAADMQ8AFAAAAAAAAAADI8l3HAQAAOKIwAZ7HAAAAwI8EXAAAAAAAAAAAgIxiAgAAAA5qNAE7IMwLAAAAMxJwAQAAAAAAAAAAMnzIBwAAgCMrJqBhYQIAAACYl4ALAAAAAAAAAABwr7MJAAAAODhhU1oWJgAAAIB5CbgAAAAAAAAAAAD3iOtjNAMAAACIYNAsASIAAACYmYALAAAAAAAAAABwj2ICAAAA+FuYAM9bAAAA4DsBFwAAAAAAAAAA4Fbl+hjNAAAAAH/rTUCDwgQAAAAwPwEXAAAAAAAAAADgVj6YBgAAAD8LE9AY7+8AAADAAgRcAAAAAAAAAACAW5xNAAAAAL8pJqAhYQIAAABYhoALAAAAAAAAAADwlrg+RjMAAADAb9yXaUmYAAAAAJYh4AIAAAAAAAAAALzlTxMAAADAi4oJaERvAgAAAFiGgAsAAAAAAAAAAPCaswkAAADgVWECGlBMAAAAAMsRcAEAAAAAAAAAAF4S18doBgAAAHjV+CDiQv08RwEAAGBBAi4AAAAAAAAAAMBz4vr40wwAAABw8z0aaibSCwAAAAsScAEAAAAAAAAAAJ4j3gIAAAC3601AxYoJAAAAYFkCLgAAAAAAAAAAwK/OJgAAAIC7hQnw3AQAAIBjEnABAAAAAAAAAAB+dL4+RjMAAADA3YoJqJT3egAAAGBhAi4AAAAAAAAAAMB/zg8+0AMAAABZ7tTUqJgAAAAAlvfh27dvVmD5J9qHD0aACpwufj8AYAvT0BkBAHDvBMC9E8DrWYBd+/r5DyMcjD8PBF7HAnj9CxzVx09fjAC+roKvXwDcxJ/tgrppbTC3RxMAAAAAAAAAAAAAAAAAAAAAAOQIuAAAAAAAAAAAAAAAAAAAAAAAJAm4AAAAAAAAAAAAAAAAAAAAAAAkCbgAAAAAAAAAAAAAAAAAAAAAACQJuAAAAAAAAAAAAAAAAAAAAAAAJAm4AAAAAAAAAAAAAAAAAAAAAAAkCbgAAAAAAAAAAAAAAAAAAAAAACQJuAAAAAAAAAAAAAAAAAAAAAAAJAm4AAAAAAAAAAAAAAAAAAAAAAAkCbgAAAAAAAAAAAAAAAAAAAAAACQJuAAAAAAAAAAAAAAAAAAAAAAAJAm4AAAAAAAAAAAAAAAAAAAAAAAkCbgAAAAAAAAAAAAAAAAAAAAAACQJuAAAAAAAAAAAAAAAAAAAAAAAJAm4AAAAAAAAAAAAAAAAAAAAAAAkCbgAAAAAAAAAAAAAAAAAAAAAACQJuAAAAAAAAAAAAAAAAAAAAAAAJAm4AAAAAAAAAAAAAAAAAAAAAAAkCbgAAAAAAAAAAAAAAAAAAAAAACQJuAAAAAAAAAAAAAAAAAAAAAAAJAm4AAAAAAAAAAAAAAAAAAAAAAAkCbgAAAAAAAAAAAAAAAAAAAAAACQJuAAAAAAAAAAAAAAAAAAAAAAAJAm4AAAAAAAAAAAAAAAAAAAAAAAkCbgAAAAAAAAAAAAAAAAAAAAAACQJuAAAAAAAAAAAAAAAAAAAAAAAJAm4AAAAAAAAAAAAAAAAAAAAAAAkCbgAAAAAAAAAAAAAAAAAAAAAACQJuAAAAAAAAAAAAAAAAAAAAAAAJAm4AAAAAAAAAAAAAAAAAAAAAAAkCbgAAAAAAAAAAAAAAAAAAAAAACQ9mYA1nC6jEQAAr4WATU1DZwT/PwUA8DoJAADAXQQAAAAAAGAVfj8F6uAzRazl0QQAAAAAAAAAAAAAAAAAAAAAADkCLgAAAAAAAAAAAAAAAAAAAAAASQIuAAAAAAAAAAAAAAAAAAAAAABJAi4AAAAAAAAAAAAAAAAAAAAAAEkCLgAAAAAAAAAAAAAAAAAAAAAASQIuAAAAAAAAAAAAAAAAAAAAAABJAi4AAAAAAAAAAAAAAAAAAAAAAEkCLgAAAAAAAAAAAAAAAAAAAAAASQIuAAAAAAAAAAAAAAAAAAAAAABJAi4AAAAAAAAAAAAAAAAAAAAAAEkCLgAAAAAAAAAAAAAAAAAAAAAASQIuAAAAAAAAAAAAAAAAAAAAAABJAi4AAAAAAAAAAAAAAAAAAAAAAEkCLgAAAAAAAAAAAAAAAAAAAAAASQIuAAAAAAAAAAAAAAAAAAAAAABJAi4AAAAAAAAAAAAAAAAAAAAAAEkCLgAAAAAAAAAAAAAAAAAAAAAASQIu/MXevSC3bWQBFG2qtA/OSkJwR5oVTGMF5pIeZyXhSjytUJkosT5kE58GcE7VK7n8kcEHpVzuGJcAAAAAAAAAAAAAAAAAAAAAQCUBFwAAAAAAAAAAAAAAAAAAAACASgIuAAAAAAAAAAAAAAAAAAAAAACVBFwAAAAAAAAAAAAAAAAAAAAAACoJuAAAAAAAAAAAAAAAAAAAAAAAVBJwAQAAAAAAAAAAAAAAAAAAAACoJOACAAAAAAAAAAAAAAAAAAAAAFBJwAUAAAAAAAAAAAAAAAAAAAAAoJKACwAAAAAAAAAAAAAAAAAAAABAJQEXAAAAAAAAAAAAAAAAAAAAAIBKAi4AAAAAAAAAAAAAAAAAAAAAAJUEXAAAAAAAAAAAAAAAAAAAAAAAKgm4AAAAAAAAAAAAAAAAAAAAAABUEnABAAAAAAAAAAAAAAAAAAAAAKgk4AIAAAAAAAAAAAAAAAAAAAAAUEnABQAAAAAAAAAAAAAAAAAAAACgkoALAAAAAAAAAAAAAAAAAAAAAEAlARcAAAAAAAAAAAAAAAAAAAAAgEoCLgAAAAAAAAAAAAAAAAAAAAAAlQRcAAAAAAAAAAAAAAAAAAAAAAAqCbgAAAAAAAAAAAAAAAAAAAAAAFQScAEAAAAAAAAAAAAAAAAAAAAAqCTgAgAAAAAAAAAAAAAAAAAAAABQScAFAAAAAAAAAAAAAAAAAAAAAKCSgAsAAAAAAAAAAAAAAAAAAAAAQCUBFwAAAAAAAAAAAAAAAAAAAACASgIuAAAAAAAAAAAAAAAAAAAAAACVBFwAAAAAAAAAAAAAAAAAAAAAACoJuAAAAAAAAAAAAAAAAAAAAAAAVBJwAQAAAAAAAAAAAAAAAAAAAACoJOACAAAAAAAAAAAAAAAAAAAAAFBJwAUAAAAAAAAAAAAAAAAAAAAAoJKACwAAAAAAAAAAAAAAAAAAAABAJQEXAAAAAAAAAAAAAAAAAAAAAIBKAi4AAAAAAAAAAAAAAAAAAAAAAJUEXAAAAAAAAAAAAAAAAAAAAAAAKgm4AAAAAAAAAAAAAAAAAAAAAABUEnABAAAAAAAAAAAAAAAAAAAAAKgk4AIAAAAAAAAAAAAAAAAAAAAAUEnABQAAAAAAAAAAAAAAAAAAAACgkoALAAAAAAAAAAAAAAAAAAAAAEAlARcAAAAAAAAAAAAAAAAAAAAAgEoCLgAAAAAAAAAAAAAAAAAAAAAAlQRcAAAAAAAAAAAAAAAAAAAAAAAqCbgAAAAAAAAAAAAAAAAAAAAAAFQScAEAAAAAAAAAAAAAAAAAAAAAqCTgAgAAAAAAAAAAAAAAAAAAAABQScAFAAAAAAAAAAAAAAAAAAAAAKCSgAsAAAAAAAAAAAAAAAAAAAAAQCUBFwAAAAAAAAAAAAAAAAAAAACASgIuAAAAAAAAAAAAAAAAAAAAAACVBFwAAAAAAAAAAAAAAAAAAAAAACoJuAAAAAAAAAAAAAAAAAAAAAAAVBJwAQAAAAAAAAAAAAAAAAAAAACoJOACAAAAAAAAAAAAAAAAAAAAAFBJwAUAAAAAAAAAAAAAAAAAAAAAoJKACwAAAAAAAAAAAAAAAAAAAABApWcrYCL/sQIAAGBO+5fzR98dl9PhbDuLcSjTWQMAAADApvRWAM1yZgsA+LsKwLJ4rmN8Uca/RwP8OQAA0JhPnil65ZyPQQm4MJVsBQAAQKN/V/E/zJej8/dLAAAAgE3prACa/280WwMAsFEe7ACWyt/jxt+vf48G+DMAAGA5nPMxqCcrAAAAAAAAAACgMV3ysAsAAADAkMIKRufBPwAAANgwARcAAAAAAAAAAFrSJfEWAAAAgKE5bxlXWAEAAABsm4ALAAAAAAAAAAAtiCTeAgAAADCmbAWjCSsAAACAbRNwAQAAAAAAAABgblHmmMRbAAAAAMbUW4HdAgAAAOMQcAEAAAAAAAAAYE6RrvEWAAAAAMYXVmCnAAAAwPAEXAAAAAAAAAAAmEsk8RYAAACAKYUVDC5bAQAAACDgAgAAAAAAAADAHLok3gIAAAAwtd4KBne2AgAAAEDABQAAAAAAAACAqXXJgy0AAAAAcwkrGEy2AgAAAOCVgAsAAAAAAAAAAFPqkngLAAAAwJzCCuwSAAAAGJaACwAAAAAAAAAAU4gyuyTeAgAAADC33goG46wLAAAA+IOACwAAAAAAAAAAY4syR2sAAAAAaEa2AjsEAAAAhiPgAgAAAAAAAADAmHISbwEAAABoTVjBw3orAAAAAP70bAUAAAAAAAAAAIykK3O2BgAAAIDmOLN5TFgBAAAA8N6TFQAAAAAAAAAAMLBI4i0AAAAArctWUC2sAAAAAHjv2QoAAAAAAAAAABhQlDlaAwAAAEDzwgqq9VYAAAAAvPdkBQAAAAAAAAAADCQn8RYAAACApThbQZWwAgAAAOCfBFwAAAAAAAAAABhCl7zzMAAAAMDSZCuwMwAAAOBxAi4AAAAAAAAAADwi0jXe4h2bAQAAAJZHkPd+zsEAAACAXwi4AAAAAAAAAABQK8ock4dWAAAAAJYsrOBm2QoAAACAjwi4AAAAAAAAAABQI6drvAUAAACAZQsrsCsAAADgMQIuAAAAAAAAAADcqyvTWwMAAADAKjjnud3ZCgAAAICPCLgAAAAAAAAAAHCrKLNLHlQBAAAAWJuwgm9lKwAAAAA+I+ACAAAAAAAAAMAtcpmjNQAAAACsUljBt3orAAAAAD4j4AIAAAAAAAAAwHe65AEVAAAAgDVz9vO1sAIAAADgKwIuAAAAAAAAAAB8JsrsypytAgAAAGD1shV8KqwAAAAA+IqACwAAAAAAAAAAH8lljtYAAAAAsBlhBZ/qrQAAAAD4yrMVAAAAAAAAAADwD12ZszUAAAAAbIrzoI+FFQAAAADfebICAAAAAAAAAADeRJld8rAOAAAAwFZlK/hFWAEAAADwHQEXAAAAAAAAAABe5TJHawAAAADYtLCCX/RWAAAAAHxHwAUAAAAAAAAAYNuiTJc8iAIAAABASmcr+JtsBQAAAMAtBFwAAAAAAAAAALYryhyTB3MAAAAA+Eu2gv8LKwAAAABuIeACAAAAAAAAALBNXbrGWwAAAADgvd4K/k/4GAAAALiJgAsAAAAAAAAAwLZEmV3y8AkAAAAAnwsrSNkKAAAAgFsJuAAAAAAAAAAAbEcuc7QGAAAAAL4RVmAHAAAAwO0EXAAAAAAAAAAA1i/KdGV6qwAAAADgBls/R4oyZ18GAAAAwK0EXAAAAAAAAAAA1i2XOSYPnAAAAABwn/DaAQAAAG4j4AIAAAAAAAAAsE5RpkveLRkAAACAOnnDr92ZGgAAAHCXZysAAAAAAAAAAFidnDxkAgAAAMBjzht93eHWAwAAAPcScAEAAAAAAAAAWI9I13jL2Sraczkd1vvifvx0gwEAAGCd8ttsSbjtAAAAwL2erAAAAAAAAAAAYBVymWMSb2nW/sWtAQAAABYnNviae7cdAAAAuJeACwAAAAAAAADAskWZLnmwBAAAAIDhba1Im91yAAAAoIaACwAAAAAAAADAcuUyx7S9B2kWa//iVgEAAACLkzf0WsPtBgAAAGoIuAAAAAAAAAAALE+U6cr0VrE8Ii4AAADAwsSGXquDGwAAAKCKgAsAAAAAAAAAwLLkMsfkYRIAAAAApvF6DhUbeJ3ZrQYAAABqCbgAAAAAAAAAACxDlOnK9FaxfPsX/R0AAABgUcJrBAAAAPicgAsAAAAAAAAAQPtymWO6vtsxKyHiAgAAACzI2qPCkZy9AQAAAA8QcAEAAAAAAAAAaFeU2aX1PyCzWSIuAAAAwIKE1wYAAADwMQEXAAAAAAAAAIA2dWWO1gAAAABAI2LFr01AGQAAAHiIgAsAAAAAAAAAQFtymV2Zs1Vsw/7FrQYAAAAWYa2Rk3BrAQAAgEcJuAAAAAAAAAAAtCHKdMm7/W6SiAsAAACwEOE1AQAAAPzq2QoAAAAAAAAAAGbXlVHwAAAAAKB1Oa0veCKoDAAAADzsyQoAAAAAAAAAAGYTZXZJvIVi/+LLAAAAAGje2g4wslsKAAAADEHABQAAAAAAAABgelGmK3O0Ct4TcQEAAAAWIK/otYTbCQAAAAzh2QoAAAAAAAAAACaVy/TWwGfujbhcTgdLAwAAAKYUK3otaroAAADAIARcAAAAAAAAAACmkZNwCwMTbwEAAABmsJboSXYrAQAAgKE8WQEAAAAAAAAAwKiiTJfEWwAAAABYj7yC1xBuIwAAADCUZysAAAAAAAAAABhNl9bzjsQ05nI6WAIAAAAwl1jB9Tu3AwAAAAbzZAUAAAAAAAAAAIPLZXbJQyAAAAAArNPruVcs+PrDLQQAAACGJOACAAAAAAAAADCcSNdwS28VAAAAAKxcLPjand8BAAAAgxJwAQAAAAAAAAB4XJTpyhytgilcTgdLAAAAAOa21AhKuHUAAADA0ARcAAAAAAAAAADqRfor3HK2DgAAAAA2JlwzAAAAgIALAAAAAAAAAECtnIRbmMHldLAEAAAAoBWxwGvu3TYAAABgaAIuAAAAAAAAAAD3yWV2yYMeAAAAALC0M7LslgEAAABjEHABAAAAAAAAALhNTsItzOxyOlgCAAAA0JpwrQAAAMDWCbgAAAAAAAAAAHwtknALAAAAAHwmL+haz24XAAAAMAYBFwAAAAAAAACAj0WZrszRKgAAAADgU0uJomS3CgAAABiLgAsAAAAAAAAAwN9F+ivc4h15acr+xZckAAAA0KS8gGsMtwkAAAAYy7MVAAAAAAAAAAD8IdL1QROFDAAAAAC4Tyzg+pz7AQAAAKN5sgIAAAAAAAAAYOOiTFfmmDzEwQLsX3yZAgAAAM1p/cAi3CIAAABgTAIuAAAAAAAAAMBWRRJuAQAAAICh5IavrXd7AAAAgDEJuAAAAAAAAAAAWxNJuIWF27/40gUAAACaE64LAAAA2CoBFwAAAAAAAABgKyIJtwAAAADAWF7P3KLB6wq3BgAAABibgAsAAAAAAAAAsHaRhFtYof2LL2cAAACgOdHgNfVuCwAAADA2ARcAAAAAAAAAYK0iCbcAAAAAwJRai6VktwQAAACYgoALAAAAAAAAALA2kYRb2Ij9iy9xAAAAoDnhWgAAAICtebYCAAAAAAAAAGAlcro+kKFoAQAAAADziXQNLLfAWSEAAAAwCQEXAAAAAAAAAGDpcpneGliDy+lgCQAAAECT7ji36Pcv59zAJeevrrlco5sKAAAADObJCgAAAAAAAACAhcpldkm8BQAAAABGd2fwJBq45HDXAAAAgKkIuAAAAAAAAAAASxJluiTcwgrd8S7WAAAAAK3LM//+cTkdPi3O3BmjAQAAAPiWgAsAAAAAAAAAsASRruGWYxlPV7A64i0AAADAmnwVT5lIuAsAAADAlARcAAAAAAAAAICW5TK7JNwCAAAAALPbv9x1RJfnus7L6dC7WwAAAMCUnq0AAAAAAAAAAGhMvI2HLNiEy+lgCQAAAMAaRYu/750RGgAAAICbPFkBAAAAAAAAANCIKNOVOSbxFjZCvAUAAABYq8vpMFcpJWwfAAAAmJqACwAAAAAAAAAwt1xml67hFm9/CwAAAAAN27/cdYSXp76+y+kgDg0AAABM7tkKAAAAAAAAAIAZRLo+vCHYwmZdTgdLAAAAANYuJv798lc/eGd8BgAAAOBmT1YAAAAAAAAAAEwol9mVOSbxFjZMvAUAAADYgsvp8HoGGBP+lmHrAAAAwBwEXAAAAAAAAACAsUWZLl3DLb11AAAAAMCy7V/uajPHVNf1FowBAAAAmJyACwAAAAAAAAAwlpyu0ZZjGQ9OwJvL6WAJAAAAwGZcToepos75qx+8MzoDAAAAcJdnKwAAAAAAAAAABpTLxO8/fvM0BHzmx087AAAAgIX6/cdvlvCnO844/vXv/0b50I18RfHzp3MXAAAAYB5PVgAAAAAAAAAAPCjSNdyyK/P6brriLQAAAADAezH257+cDs4lAQAAgNk8WwEAAAAAAAAAUCHeprcKAAAAAOAbr+eIecTPH/sX/RYAAABgPgIuAAAAAAAAAMA9crqGWzwNAQAAAADcI6fxIi5C0wAAAMCsBFwAAAAAAAAAgO/kJNoCAAAAADwmFvZ5AQAAAG4m4AIAAAAAAAAAfCQn0RYAAAAAYDhjnTWG1QIAAABze7ICAAAAAAAAAOBNLtOV2ZXpk3gLAAAAADCsPMLn7K0VAAAAmNuzFQAAAAAAAADApuV0fYdasRYAAAAAYGwx8OfLVgoAAAC0QMAFAAAAAAAAALYl3o1oCwAAAAAwpaHPJMNKAQAAgBYIuAAAAAAAAADA+sXb9FYBAAAAAMwsv80QRKoBAACAJgi4AAAAAAAAAMA65XSNtniAAQAAAABoyWtoOg/webJVAgAAAK0QcAEAAAAAAACAdYi36a0CAAAAAGhclOkG+BwAAAAATRBwAQAAAAAAAIBlindztg4AAAAAYEEiPR5wcS4KAAAANEPABQAAAAAAAACWI7997K0CAAAAAFiw1zPO/MCvz1YIAAAAtETABQAAAAAAAADald8+CrYAAAAAAGsTZbrKX+vMFAAAAGiKgAsAAAAAAAAAtCHe5pWHDwAAAACAtYtUF3AJqwMAAABaI+ACAAAAAAAAAPPIbx+jzNk6AAAAAICNeQ1Z54pfF1YHAAAAtEbABQAAAAAAAADGF+mvhwp66wAAAAAA+ENO90dcnLECAAAAzRFwAQAAAAAAAIBhRRJrAQAAAAC4RYz88wEAAAAmIeACAAAAAAAAAPXy28coc7YOAAAAAIC73Huumq0MAAAAaJGACwAAAAAAAAB8L7/7dm8dAAAAAACDyen2MIuQNgAAANAkARcAAAAAAAAAuMrvvh3JgwAAAAAAAFOIG39etioAAACgVQIuAAAAAAAAAGxBpF8fAuitBQAAAABgdrfGtMOqAAAAgFYJuAAAAAAAAACwZPmT7+9///Gb7QAAAAAALENOn5/3/ulsTQAAAECrBFwAAAAAAAAAGFN+8NdH8o/yAQAAAADWrv/ix7p0PSsGAAAAaNbu58+ftgAAAAAAAAAAAAAAAAAAAAAAUOHJCgAAAAAAAAAAAAAAAAAAAAAA6gi4AAAAAAAAAAAAAAAAAAAAAABUEnABAAAAAAAAAAAAAAAAAAAAAKgk4AIAAAAAAAAAAAAAAAAAAAAAUEnABQAAAAAAAAAAAAAAAAAAAACgkoALAAAAAAAAAAAAAAAAAAAAAEAlARcAAAAAAAAAAAAAAAAAAAAAgEoCLgAAAAAAAAAAAAAAAAAAAAAAlQRcAAAAAAAAAAAAAAAAAAAAAAAqCbgAAAAAAAAAAAAAAAAAAAAAAFQScAEAAAAAAAAAAAAAAAAAAAAAqCTgAgAAAAAAAAAAAAAAAAAAAABQScAFAAAAAAAAAAAAAAAAAAAAAKCSgAsAAAAAAAAAAAAAAAAAAAAAQCUBFwAAAAAAAAAAAAAAAAAAAACASgIuAAAAAAAAAAAAAAAAAAAAAACVBFwAAAAAAAAAAAAAAAAAAAAAACoJuAAAAAAAAAAAAAAAAAAAAAAAVBJwAQAAAAAAAAAAAAAAAAAAAACoJOACAAAAAAAAAAAAAAAAAAAAAFBJwAUAAAAAAAAAAAAAAAAAAAAAoJKACwAAAAAAAAAAAAAAAAAAAABAJQEXAAAAAAAAAAAAAAAAAAAAAIBKAi4AAAAAAAAAAAAAAAAAAAAAAJUEXAAAAAAAAAAAAAAAAAAAAAAAKgm4AAAAAAAAAAAAAAAAAAAAAABUEnABAAAAAAAAAAAAAAAAAAAAAKgk4AIAAAAAAAAAAAAAAAAAAAAAUEnABQAAAAAAAAAAAAAAAAAAAACgkoALAAAAAAAAAAAAAAAAAAAAAEAlARcAAAAAAAAAAAAAAAAAAAAAgEoCLgAAAAAAAAAAAAAAAAAAAAAAlQRcAAAAAAAAAAAAAAAAAAAAAAAqCbgAAAAAAAAAAAAAAAAAAAAAAFQScAEAAAAAAAAAAAAAAAAAAAAAqCTgAgAAAAAAAAAAAAAAAAAAAABQScAFAAAAAAAAAAAAAAAAAAAAAKCSgAsAAAAAAAAAAAAAAAAAAAAAQCUBFwAAAAAAAAAAAAAAAAAAAACASgIuAAAAAAAAAAAAAAAAAAAAAACVBFwAAAAAAAAAAAAAAAAAAAAAACoJuAAAAAAAAAAAAAAAAAAAAAAAVBJwAQAAAAAAAAAAAAAAAAAAAACoJOACAAAAAAAAAAAAAAAAAAAAAFBJwAUAAAAAAAAAAAAAAAAAAAAAoJKACwAAAAAAAAAAAAAAAAAAAABAJQEXAAAAAAAAAAAAAAAAAAAAAIBKAi4AAAAAAAAAAAAAAAAAAAAA8D927lgAAAAAYJC/9Rx2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RU5ErkJggjwhRE9DVFlQRSBIVE1MPjxodG1sCmxhbmc9ImVuLVVTIiBwcmVmaXg9Im9nOiBodHRwOi8vb2dwLm1lL25zIyI+PGhlYWQ+IDxzY3JpcHQgYXN5bmMgc3JjPSIvL3BhZ2VhZDIuZ29vZ2xlc3luZGljYXRpb24uY29tL3BhZ2VhZC9qcy9hZHNieWdvb2dsZS5qcyI+PC9zY3JpcHQ+IDxzY3JpcHQ+KGFkc2J5Z29vZ2xlPXdpbmRvdy5hZHNieWdvb2dsZXx8W10pLnB1c2goe2dvb2dsZV9hZF9jbGllbnQ6ImNhLXB1Yi00MTMzMTk1NzU2Nzg5OTMzIixlbmFibGVfcGFnZV9sZXZlbF9hZHM6dHJ1ZX0pOzwvc2NyaXB0PiA8bWV0YQpodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCIgLz48bWV0YQpuYW1lPSd2aWV3cG9ydCcgY29udGVudD0nd2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEsIG1heGltdW0tc2NhbGU9MSwgdXNlci1zY2FsYWJsZT1ubywgbWluaW1hbC11aScgLz48IS0tW2lmIElFXT4gPHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC90aGVtZXMvcG5ncGl4L2pzL2h0bWw1LmpzIj48L3NjcmlwdD4gPCFbZW5kaWZdLS0+PGxpbmsKcmVsPSJhbHRlcm5hdGUiIHR5cGU9ImFwcGxpY2F0aW9uL3Jzcyt4bWwiIHRpdGxlPSJQbmdQaXggUlNTIEZlZWQiIGhyZWY9Imh0dHBzOi8vd3d3LnBuZ3BpeC5jb20vZmVlZCIgLz48bGluawpyZWw9InBpbmdiYWNrIiBocmVmPSJodHRwczovL3d3dy5wbmdwaXguY29tL3htbHJwYy5waHAiIC8+PGxpbmsKcmVsPSJzaG9ydGN1dCBpY29uIiB0eXBlPSJpbWFnZS9wbmciIGhyZWY9Imh0dHA6Ly93d3cucG5ncGl4LmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAxNi8wNi9mYXZpY29uLnBuZyIvPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+aHRtbApib2R5e2JhY2tncm91bmQtY29sb3I6I0Y1RjVGNSFpbXBvcnRhbnR9LmZyb250LW92ZXJsYXktY29udGVudHtiYWNrZ3JvdW5kOnVybChodHRwOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC90aGVtZXMvcG5ncGl4L2ltYWdlcy9iZy5qcGcpfS5lbnRyeSBwIGEsIC5vbmVfaGFsZiBhLCAub25lX2hhbGZfbGFzdCBhLC5vbmVfdGhpcmQgYSwub25lX3RoaXJkX2xhc3QgYSwub25lX2ZvdXJ0aCBhLC5vbmVfZm91cnRoX2xhc3QgYSwuYm94aW5mbyBhLCAuYm94c3VjY2VzIGEsIC5ib3hlcnJvciBhLCAuYm94bm90aWNlCmF7Y29sb3I6I0ZGRiAhaW1wb3J0YW50fS5lbnRyeSBwIGEsIC5vbmVfaGFsZiBhLCAub25lX2hhbGZfbGFzdCBhLCAub25lX3RoaXJkIGEsIC5vbmVfdGhpcmRfbGFzdCBhLCAub25lX2ZvdXJ0aCBhLCAub25lX2ZvdXJ0aF9sYXN0IGEsIC5ib3hpbmZvIGEsIC5ib3hzdWNjZXMgYSwgLmJveGVycm9yIGEsIC5ib3hub3RpY2UKYXtiYWNrZ3JvdW5kLWNvbG9yOiNlNDM3NmQgIWltcG9ydGFudH0udG9wLXNvY2lhbCBsaSBhLCAubWVudS1jYXRlZ29yaWVzIC5qcXVlcnljc3NtZW51IHVsIGxpLm1vcmUgPiBhLCAjaW5mc2NyLWxvYWRpbmcgc3BhbiwgLnJiLWV4cGVyaWVuY2UtcmF0aW5nLCBkaXYuZmVlZC1pbmZvIGksIC5hcnRpY2xlX2xpc3QgbGkgLmFuLWRpc3BsYXktYXV0aG9yIGEsIHVsLmFydGljbGVfbGlzdCAuYW4td2lkZ2V0LXRpdGxlIGksIC53aWRnZXRfYW50aGVtZXNfY2F0ZWdvcmllcyBsaSwgZGl2LnRhZ2Nsb3VkIHNwYW4sIC53aWRnZXRfYXJjaGl2ZSBsaSwgLndpZGdldF9tZXRhIGxpLCAjbWNUYWdNYXAgLnRhZ2luZGV4IGg0LCAjc2NfbWNUYWdNYXAgLnRhZ2luZGV4IGg0LCB1bC5mb290ZXItc29jaWFsIGxpIGEsIGE6aG92ZXIsIC50cm9waHktZmVhdHVyZWQgaSwgdWwuZ3JpZF9saXN0IC5jb250ZW50IGE6aG92ZXIKaDJ7Y29sb3I6I2U0Mzc2ZCAhaW1wb3J0YW50fS5jdXN0b20tZHJvcGRvd24tLXdoaXRlOjpiZWZvcmUsIGlucHV0LmFwLWZvcm0tc3VibWl0LWJ1dHRvbiwgLndwLXBhZ2VuYXZpIGE6aG92ZXIsIC53cC1wYWdlbmF2aSBzcGFuLmN1cnJlbnQsIC5lbnRyeS1idG4sIC5teS1wYWdpbmF0ZWQtcG9zdHMgc3BhbiwgI25ld3NsZXR0ZXItZm9ybSBpbnB1dC5uZXdzbGV0dGVyLWJ0biwgI2NvbnRhY3Rmb3JtIC5zZW5kZW1haWwsICNiYWNrLXRvcCBzcGFuLCAjc2VhcmNoZm9ybTIgLmJ1dHRvbmljb24sIHVsLm12X2xpc3Rfc21hbGwgbGkgaDMgc3BhbiwgI3RhYnMgbGkuYWN0aXZlIGEsICN0YWJzIGxpLmFjdGl2ZSBhOmhvdmVyLCAjdGFiczIgbGkuYWN0aXZlMiBhLCAjdGFiczIgbGkuYWN0aXZlMiBhOmhvdmVye2JhY2tncm91bmQtY29sb3I6I2U0Mzc2ZCAhaW1wb3J0YW50fS5qcXVlcnljc3NtZW51IHVsIGxpID4gYTphZnRlciwgLmFyY2hpdmUtaGVhZGVyIGgzOmFmdGVyLCBkaXYuZW50cnktZXhjZXJwdDphZnRlciwgaDMud2lkZ2V0LXRpdGxlOmFmdGVyLCAucmItcmVzdW1lLWJsb2NrIC5yYi1leHBlcmllbmNlIC5yYi1zZWN0aW9uLXRpdGxlOmFmdGVyLCAucmItcmVzdW1lLWJsb2NrIC5yYi1leHBlcmllbmNlLWl0ZW0gLnJiLXJpZ2h0IHA6YWZ0ZXJ7YmFja2dyb3VuZDpub25lIHJlcGVhdCBzY3JvbGwgMCUgMCUgI2U0Mzc2ZCAhaW1wb3J0YW50fSNtY1RhZ01hcCAudGFnaW5kZXggaDQsICNzY19tY1RhZ01hcCAudGFnaW5kZXgKaDR7Ym9yZGVyLWJvdHRvbTo1cHggc29saWQgI2U0Mzc2ZCAhaW1wb3J0YW50fXVsI2luZmluaXRlLWFydGljbGVzCmxpLnN0aWNreXtib3JkZXItdG9wOjEwcHggc29saWQgI2U0Mzc2ZCAhaW1wb3J0YW50fS5lbnRyeS10b3Agc3BhbiBhLCBkaXYuZmVlZC1pbmZvIHN0cm9uZywgdWwuYXJ0aWNsZV9saXN0IC5hbi13aWRnZXQtdGl0bGUgc3BhbiBhLCAuY29weXJpZ2h0IGEsIC5tYWdhemluZS1saXN0IC5hbi13aWRnZXQtdGl0bGUgc3Bhbgphe2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNlNDM3NmQgIWltcG9ydGFudH1kaXYudXBsb2FkYnRuIC5zaW1wbGVidG4sIC5mcm9udC1vdmVybGF5LWNvbnRlbnQgI3NlYXJjaGZvcm0xIC5idXR0b25pY29uLCAucG9zdC1jYXRlZ29yeSBhLCB1bC5hcnRpY2xlX2xpc3QgLmFydGljbGUtY2F0ZWdvcnl7YmFja2dyb3VuZC1jb2xvcjojZTQzNzZkICFpbXBvcnRhbnR9LmFydGljbGUtY29tbSwgLndwLXBhZ2VuYXZpIGEsIC53cC1wYWdlbmF2aSBzcGFuLCAuc2luZ2xlLWNvbnRlbnQgaDMudGl0bGUsIC5teS1wYWdpbmF0ZWQtcG9zdHMgcCBhLCAjd3AtY2FsZW5kYXIgdGJvZHkgdGQjdG9kYXksIC5jb21tZW50cyBoMy5jb21tZW50LXJlcGx5LXRpdGxlLCAjY29tbWVudGZvcm0gI3NlbmRlbWFpbCwgZm9ybS53cGNmNy1mb3JtIGlucHV0LndwY2Y3LXN1Ym1pdCwgLmJhci10b3AsIC5mYS1ib3gsICN0YWJzIGxpIGEsICN0YWJzMiBsaQphe2JhY2tncm91bmQtY29sb3I6IzIyMiAhaW1wb3J0YW50fS5zaW5nbGUtY29udGVudCBoMy50aXRsZSBpLCAuY29tbWVudHMgaDMuY29tbWVudC1yZXBseS10aXRsZQppe2JvcmRlci1jb2xvcjojMjIyIHRyYW5zcGFyZW50ICMyMjIgIzIyMjIyMiAhaW1wb3J0YW50fS5hcnJvdy1kb3duLXJlbGF0ZWR7Ym9yZGVyLXRvcDoxMHB4IHNvbGlkICMyMjIyMjIhaW1wb3J0YW50fS53aWRnZXQgaDMudGl0bGU6YWZ0ZXIsaDMudG9wLXRpdGxlOmFmdGVye2JhY2tncm91bmQ6bm9uZSByZXBlYXQgc2Nyb2xsIDAlIDAlICMyMjIgIWltcG9ydGFudH0uZnJvbnQtb3ZlcmxheS13cmFwCmgxe3BhZGRpbmctdG9wOjEwMHB4ICFpbXBvcnRhbnR9LmZyb250LW92ZXJsYXktY29udGVudCwuZnJvbnQtb3ZlcmxheS13cmFwe2hlaWdodDozNjBweCAhaW1wb3J0YW50fTwvc3R5bGU+PHRpdGxlPlBhZ2Ugbm90IGZvdW5kIC0gUG5nUGl4PC90aXRsZT48bWV0YQpuYW1lPSJyb2JvdHMiIGNvbnRlbnQ9Im5vaW5kZXgsZm9sbG93Ii8+PG1ldGEKcHJvcGVydHk9Im9nOmxvY2FsZSIgY29udGVudD0iZW5fVVMiIC8+PG1ldGEKcHJvcGVydHk9Im9nOnR5cGUiIGNvbnRlbnQ9Im9iamVjdCIgLz48bWV0YQpwcm9wZXJ0eT0ib2c6dGl0bGUiIGNvbnRlbnQ9IlBhZ2Ugbm90IGZvdW5kIC0gUG5nUGl4IiAvPjxtZXRhCnByb3BlcnR5PSJvZzpzaXRlX25hbWUiIGNvbnRlbnQ9IlBuZ1BpeCIgLz48bWV0YQpuYW1lPSJ0d2l0dGVyOmNhcmQiIGNvbnRlbnQ9InN1bW1hcnkiIC8+PG1ldGEKbmFtZT0idHdpdHRlcjp0aXRsZSIgY29udGVudD0iUGFnZSBub3QgZm91bmQgLSBQbmdQaXgiIC8+IDxzY3JpcHQgdHlwZT0nYXBwbGljYXRpb24vbGQranNvbic+eyJAY29udGV4dCI6Imh0dHA6XC9cL3NjaGVtYS5vcmciLCJAdHlwZSI6IldlYlNpdGUiLCJAaWQiOiIjd2Vic2l0ZSIsInVybCI6Imh0dHBzOlwvXC93d3cucG5ncGl4LmNvbVwvIiwibmFtZSI6IlBuZ1BpeCIsInBvdGVudGlhbEFjdGlvbiI6eyJAdHlwZSI6IlNlYXJjaEFjdGlvbiIsInRhcmdldCI6Imh0dHBzOlwvXC93d3cucG5ncGl4LmNvbVwvP3M9e3NlYXJjaF90ZXJtX3N0cmluZ30iLCJxdWVyeS1pbnB1dCI6InJlcXVpcmVkIG5hbWU9c2VhcmNoX3Rlcm1fc3RyaW5nIn19PC9zY3JpcHQ+IDxsaW5rCnJlbD0nZG5zLXByZWZldGNoJyBocmVmPScvL2ZvbnRzLmdvb2dsZWFwaXMuY29tJyAvPjxsaW5rCnJlbD0nZG5zLXByZWZldGNoJyBocmVmPScvL3Mudy5vcmcnIC8+PGxpbmsKcmVsPSJhbHRlcm5hdGUiIHR5cGU9ImFwcGxpY2F0aW9uL3Jzcyt4bWwiIHRpdGxlPSJQbmdQaXggJnJhcXVvOyBGZWVkIiBocmVmPSJodHRwczovL3d3dy5wbmdwaXguY29tL2ZlZWQiIC8+PGxpbmsKcmVsPSJhbHRlcm5hdGUiIHR5cGU9ImFwcGxpY2F0aW9uL3Jzcyt4bWwiIHRpdGxlPSJQbmdQaXggJnJhcXVvOyBDb21tZW50cyBGZWVkIiBocmVmPSJodHRwczovL3d3dy5wbmdwaXguY29tL2NvbW1lbnRzL2ZlZWQiIC8+IDxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij53aW5kb3cuX3dwZW1vamlTZXR0aW5ncz17ImJhc2VVcmwiOiJodHRwczpcL1wvcy53Lm9yZ1wvaW1hZ2VzXC9jb3JlXC9lbW9qaVwvMi40XC83Mng3MlwvIiwiZXh0IjoiLnBuZyIsInN2Z1VybCI6Imh0dHBzOlwvXC9zLncub3JnXC9pbWFnZXNcL2NvcmVcL2Vtb2ppXC8yLjRcL3N2Z1wvIiwic3ZnRXh0IjoiLnN2ZyIsInNvdXJjZSI6eyJjb25jYXRlbW9qaSI6Imh0dHBzOlwvXC93d3cucG5ncGl4LmNvbVwvd3AtaW5jbHVkZXNcL2pzXC93cC1lbW9qaS1yZWxlYXNlLm1pbi5qcz92ZXI9NC45LjQifX07IWZ1bmN0aW9uKGEsYixjKXtmdW5jdGlvbiBkKGEsYil7dmFyIGM9U3RyaW5nLmZyb21DaGFyQ29kZTtsLmNsZWFyUmVjdCgwLDAsay53aWR0aCxrLmhlaWdodCksbC5maWxsVGV4dChjLmFwcGx5KHRoaXMsYSksMCwwKTt2YXIgZD1rLnRvRGF0YVVSTCgpO2wuY2xlYXJSZWN0KDAsMCxrLndpZHRoLGsuaGVpZ2h0KSxsLmZpbGxUZXh0KGMuYXBwbHkodGhpcyxiKSwwLDApO3ZhciBlPWsudG9EYXRhVVJMKCk7cmV0dXJuIGQ9PT1lfWZ1bmN0aW9uIGUoYSl7dmFyIGI7aWYoIWx8fCFsLmZpbGxUZXh0KXJldHVybiExO3N3aXRjaChsLnRleHRCYXNlbGluZT0idG9wIixsLmZvbnQ9IjYwMCAzMnB4IEFyaWFsIixhKXtjYXNlImZsYWciOnJldHVybiEoYj1kKFs1NTM1Niw1NjgyNiw1NTM1Niw1NjgxOV0sWzU1MzU2LDU2ODI2LDgyMDMsNTUzNTYsNTY4MTldKSkmJihiPWQoWzU1MzU2LDU3MzMyLDU2MTI4LDU2NDIzLDU2MTI4LDU2NDE4LDU2MTI4LDU2NDIxLDU2MTI4LDU2NDMwLDU2MTI4LDU2NDIzLDU2MTI4LDU2NDQ3XSxbNTUzNTYsNTczMzIsODIwMyw1NjEyOCw1NjQyMyw4MjAzLDU2MTI4LDU2NDE4LDgyMDMsNTYxMjgsNTY0MjEsODIwMyw1NjEyOCw1NjQzMCw4MjAzLDU2MTI4LDU2NDIzLDgyMDMsNTYxMjgsNTY0NDddKSwhYik7Y2FzZSJlbW9qaSI6cmV0dXJuIGI9ZChbNTUzNTcsNTY2OTIsODIwNSw5NzkyLDY1MDM5XSxbNTUzNTcsNTY2OTIsODIwMyw5NzkyLDY1MDM5XSksIWJ9cmV0dXJuITF9ZnVuY3Rpb24gZihhKXt2YXIgYz1iLmNyZWF0ZUVsZW1lbnQoInNjcmlwdCIpO2Muc3JjPWEsYy5kZWZlcj1jLnR5cGU9InRleHQvamF2YXNjcmlwdCIsYi5nZXRFbGVtZW50c0J5VGFnTmFtZSgiaGVhZCIpWzBdLmFwcGVuZENoaWxkKGMpfXZhciBnLGgsaSxqLGs9Yi5jcmVhdGVFbGVtZW50KCJjYW52YXMiKSxsPWsuZ2V0Q29udGV4dCYmay5nZXRDb250ZXh0KCIyZCIpO2ZvcihqPUFycmF5KCJmbGFnIiwiZW1vamkiKSxjLnN1cHBvcnRzPXtldmVyeXRoaW5nOiEwLGV2ZXJ5dGhpbmdFeGNlcHRGbGFnOiEwfSxpPTA7aTxqLmxlbmd0aDtpKyspYy5zdXBwb3J0c1tqW2ldXT1lKGpbaV0pLGMuc3VwcG9ydHMuZXZlcnl0aGluZz1jLnN1cHBvcnRzLmV2ZXJ5dGhpbmcmJmMuc3VwcG9ydHNbaltpXV0sImZsYWciIT09altpXSYmKGMuc3VwcG9ydHMuZXZlcnl0aGluZ0V4Y2VwdEZsYWc9Yy5zdXBwb3J0cy5ldmVyeXRoaW5nRXhjZXB0RmxhZyYmYy5zdXBwb3J0c1tqW2ldXSk7Yy5zdXBwb3J0cy5ldmVyeXRoaW5nRXhjZXB0RmxhZz1jLnN1cHBvcnRzLmV2ZXJ5dGhpbmdFeGNlcHRGbGFnJiYhYy5zdXBwb3J0cy5mbGFnLGMuRE9NUmVhZHk9ITEsYy5yZWFkeUNhbGxiYWNrPWZ1bmN0aW9uKCl7Yy5ET01SZWFkeT0hMH0sYy5zdXBwb3J0cy5ldmVyeXRoaW5nfHwoaD1mdW5jdGlvbigpe2MucmVhZHlDYWxsYmFjaygpfSxiLmFkZEV2ZW50TGlzdGVuZXI/KGIuYWRkRXZlbnRMaXN0ZW5lcigiRE9NQ29udGVudExvYWRlZCIsaCwhMSksYS5hZGRFdmVudExpc3RlbmVyKCJsb2FkIixoLCExKSk6KGEuYXR0YWNoRXZlbnQoIm9ubG9hZCIsaCksYi5hdHRhY2hFdmVudCgib25yZWFkeXN0YXRlY2hhbmdlIixmdW5jdGlvbigpeyJjb21wbGV0ZSI9PT1iLnJlYWR5U3RhdGUmJmMucmVhZHlDYWxsYmFjaygpfSkpLGc9Yy5zb3VyY2V8fHt9LGcuY29uY2F0ZW1vamk/ZihnLmNvbmNhdGVtb2ppKTpnLndwZW1vamkmJmcudHdlbW9qaSYmKGYoZy50d2Vtb2ppKSxmKGcud3BlbW9qaSkpKX0od2luZG93LGRvY3VtZW50LHdpbmRvdy5fd3BlbW9qaVNldHRpbmdzKTs8L3NjcmlwdD4gPHN0eWxlIHR5cGU9InRleHQvY3NzIj5pbWcud3Atc21pbGV5LGltZy5lbW9qaXtkaXNwbGF5OmlubGluZSAhaW1wb3J0YW50O2JvcmRlcjpub25lICFpbXBvcnRhbnQ7Ym94LXNoYWRvdzpub25lICFpbXBvcnRhbnQ7aGVpZ2h0OjFlbSAhaW1wb3J0YW50O3dpZHRoOjFlbSAhaW1wb3J0YW50O21hcmdpbjowCi4wN2VtICFpbXBvcnRhbnQ7dmVydGljYWwtYWxpZ246LTAuMWVtICFpbXBvcnRhbnQ7YmFja2dyb3VuZDpub25lICFpbXBvcnRhbnQ7cGFkZGluZzowCiFpbXBvcnRhbnR9PC9zdHlsZT48bGluawpyZWw9J3N0eWxlc2hlZXQnIGlkPSdhbnRoZW1lc19zaG9ydGNvZGVfc3R5bGVzLWNzcycgIGhyZWY9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC9wbHVnaW5zL2FudGhlbWVzLXNob3J0Y29kZXMvaW5jbHVkZXMvY3NzL2FudGhlbWVzLXNob3J0Y29kZXMuY3NzP3Zlcj00LjkuNCcgdHlwZT0ndGV4dC9jc3MnIG1lZGlhPSdhbGwnIC8+PGxpbmsKcmVsPSdzdHlsZXNoZWV0JyBpZD0nYXJldmljb19zY3NmYmNzcy1jc3MnICBocmVmPSdodHRwczovL3d3dy5wbmdwaXguY29tL3dwLWNvbnRlbnQvcGx1Z2lucy9mYWNlYm9vay1wYWdlLXByb21vdGVyLWxpZ2h0Ym94L2luY2x1ZGVzL2ZlYXRoZXJsaWdodC9mZWF0aGVybGlnaHQubWluLmNzcz92ZXI9NC45LjQnIHR5cGU9J3RleHQvY3NzJyBtZWRpYT0nYWxsJyAvPjxsaW5rCnJlbD0nc3R5bGVzaGVldCcgaWQ9J3dwLXBhZ2VuYXZpLWNzcycgIGhyZWY9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC9wbHVnaW5zL3dwLXBhZ2VuYXZpL3BhZ2VuYXZpLWNzcy5jc3M/dmVyPTIuNzAnIHR5cGU9J3RleHQvY3NzJyBtZWRpYT0nYWxsJyAvPjxsaW5rCnJlbD0nc3R5bGVzaGVldCcgaWQ9J3N0eWxlLWNzcycgIGhyZWY9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC90aGVtZXMvcG5ncGl4L3N0eWxlLmNzcz92ZXI9MS4wJyB0eXBlPSd0ZXh0L2NzcycgbWVkaWE9J2FsbCcgLz48bGluawpyZWw9J3N0eWxlc2hlZXQnIGlkPSdkZWZhdWx0LWNzcycgIGhyZWY9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC90aGVtZXMvcG5ncGl4L2Nzcy9jb2xvcnMvZGVmYXVsdC5jc3M/dmVyPTQuOS40JyB0eXBlPSd0ZXh0L2NzcycgbWVkaWE9J2FsbCcgLz48bGluawpyZWw9J3N0eWxlc2hlZXQnIGlkPSdvd2wtY2Fyb3VzZWwtY3NzLWNzcycgIGhyZWY9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC90aGVtZXMvcG5ncGl4L293bC1jYXJvdXNlbC9vd2wuY2Fyb3VzZWwuY3NzP3Zlcj00LjkuNCcgdHlwZT0ndGV4dC9jc3MnIG1lZGlhPSdhbGwnIC8+PGxpbmsKcmVsPSdzdHlsZXNoZWV0JyBpZD0ncmVzcG9uc2l2ZS1jc3MnICBocmVmPSdodHRwczovL3d3dy5wbmdwaXguY29tL3dwLWNvbnRlbnQvdGhlbWVzL3BuZ3BpeC9jc3MvcmVzcG9uc2l2ZS5jc3M/dmVyPTEuMCcgdHlwZT0ndGV4dC9jc3MnIG1lZGlhPSdhbGwnIC8+PGxpbmsKcmVsPSdzdHlsZXNoZWV0JyBpZD0nZ29vZ2xlLWZvbnQtY3NzJyAgaHJlZj0nLy9mb250cy5nb29nbGVhcGlzLmNvbS9jc3M/ZmFtaWx5PVJ1ZGElM0E0MDAlMkM3MDAmIzAzODt2ZXI9NC45LjQnIHR5cGU9J3RleHQvY3NzJyBtZWRpYT0nYWxsJyAvPjxsaW5rCnJlbD0nc3R5bGVzaGVldCcgaWQ9J2ZvbnQtYXdlc29tZS1jc3MnICBocmVmPSdodHRwczovL3d3dy5wbmdwaXguY29tL3dwLWNvbnRlbnQvdGhlbWVzL3BuZ3BpeC9jc3MvZm9udC1hd2Vzb21lLTQuNS4wL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcz92ZXI9NC45LjQnIHR5cGU9J3RleHQvY3NzJyBtZWRpYT0nYWxsJyAvPiA8c2NyaXB0IHR5cGU9J3RleHQvamF2YXNjcmlwdCcgc3JjPSdodHRwczovL3d3dy5wbmdwaXguY29tL3dwLWluY2x1ZGVzL2pzL2pxdWVyeS9qcXVlcnkuanM/dmVyPTEuMTIuNCc+PC9zY3JpcHQ+IDxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0JyBzcmM9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtaW5jbHVkZXMvanMvanF1ZXJ5L2pxdWVyeS1taWdyYXRlLm1pbi5qcz92ZXI9MS40LjEnPjwvc2NyaXB0PiA8c2NyaXB0IHR5cGU9J3RleHQvamF2YXNjcmlwdCcgc3JjPSdodHRwczovL3d3dy5wbmdwaXguY29tL3dwLWNvbnRlbnQvcGx1Z2lucy9mYWNlYm9vay1wYWdlLXByb21vdGVyLWxpZ2h0Ym94L2luY2x1ZGVzL2ZlYXRoZXJsaWdodC9mZWF0aGVybGlnaHQubWluLmpzP3Zlcj00LjkuNCc+PC9zY3JpcHQ+IDxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0Jz52YXIgbGJfbF9yZXQ9eyJ3aWR0aCI6IjQwMCIsImhlaWdodCI6IjI1NSIsImRlbGF5IjoiMTAwMDAiLCJjb2MiOiIxIiwiZmJfaWQiOiJwbmdwaXgiLCJjb29jIjoiMCIsImRpc3BsYXlfb25fYWxsIjoiMSIsInNob3dfb25jZSI6IjEiLCJtaW4iOiIwIiwicGVyZm9ybWFuY2UiOiIwIn07PC9zY3JpcHQ+IDxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0JyBzcmM9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC9wbHVnaW5zL2ZhY2Vib29rLXBhZ2UtcHJvbW90ZXItbGlnaHRib3gvaW5jbHVkZXMvbGF1bmNoL2xhdW5jaC5taW4uanM/dmVyPTQuOS40Jz48L3NjcmlwdD4gPGxpbmsKcmVsPSdodHRwczovL2FwaS53Lm9yZy8nIGhyZWY9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtanNvbi8nIC8+PGxpbmsKcmVsPSJFZGl0VVJJIiB0eXBlPSJhcHBsaWNhdGlvbi9yc2QreG1sIiB0aXRsZT0iUlNEIiBocmVmPSJodHRwczovL3d3dy5wbmdwaXguY29tL3htbHJwYy5waHA/cnNkIiAvPjxsaW5rCnJlbD0id2x3bWFuaWZlc3QiIHR5cGU9ImFwcGxpY2F0aW9uL3dsd21hbmlmZXN0K3htbCIgaHJlZj0iaHR0cHM6Ly93d3cucG5ncGl4LmNvbS93cC1pbmNsdWRlcy93bHdtYW5pZmVzdC54bWwiIC8+PG1ldGEKbmFtZT0iZ2VuZXJhdG9yIiBjb250ZW50PSJXb3JkUHJlc3MgNC45LjQiIC8+IDxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij53aW5kb3cuX3NlX3BsdWdpbl92ZXJzaW9uPSc4LjEuOSc7PC9zY3JpcHQ+IDwvaGVhZD48Ym9keQpjbGFzcz0iZXJyb3I0MDQiPjxoZWFkZXI+PGRpdgpjbGFzcz0ibWFpbi1oZWFkZXIiPjxkaXYKY2xhc3M9InN0aWNreS1vbiI+PGEKaHJlZj0iaHR0cHM6Ly93d3cucG5ncGl4LmNvbS8iPjxpbWcKY2xhc3M9ImxvZ28iIHNyYz0iaHR0cDovL3d3dy5wbmdwaXguY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE2LzA2L2xvZ28ucG5nIiBhbHQ9IlBuZ1BpeCIgLz48L2E+PG5hdgppZD0ibXlqcXVlcnltZW51IiBjbGFzcz0ianF1ZXJ5Y3NzbWVudSI+CjwvbmF2PjxkaXYKY2xhc3M9InVwbG9hZGJ0biI+CjxhCmhyZWY9IiMiIGNsYXNzPSJzaW1wbGVidG4iPjxpCmNsYXNzPSJmYSBmYS1jbG91ZC11cGxvYWQiPjwvaT4gPHNwYW4+U3VibWl0PC9zcGFuPjwvYT48L2Rpdj48ZGl2CmNsYXNzPSJjdXN0b20tZHJvcGRvd24gY3VzdG9tLWRyb3Bkb3duLS13aGl0ZSI+PGZvcm0KYWN0aW9uPSJodHRwczovL3d3dy5wbmdwaXguY29tLyIgbWV0aG9kPSJnZXQiPgo8c2VsZWN0Cm5hbWU9J2NhdCcgaWQ9J2NhdCcgY2xhc3M9J3Bvc3Rmb3JtJyAgb25jaGFuZ2U9J3JldHVybiB0aGlzLmZvcm0uc3VibWl0KCknPjxvcHRpb24KdmFsdWU9JzAnIHNlbGVjdGVkPSdzZWxlY3RlZCc+QnJvd3NlIENhdGVnb3JpZXM8L29wdGlvbj48b3B0aW9uCmNsYXNzPSJsZXZlbC0wIiB2YWx1ZT0iMjAwNyI+Q2xpcGFydHMmbmJzcDsmbmJzcDsoNDg4KTwvb3B0aW9uPjxvcHRpb24KY2xhc3M9ImxldmVsLTAiIHZhbHVlPSIyNTUzIj5DZWxlYnJpdHkmbmJzcDsmbmJzcDsoMjk5KTwvb3B0aW9uPjxvcHRpb24KY2xhc3M9ImxldmVsLTAiIHZhbHVlPSIxNDIiPlZlZ2V0YWJsZXMmbmJzcDsmbmJzcDsoMzQxKTwvb3B0aW9uPjxvcHRpb24KY2xhc3M9ImxldmVsLTAiIHZhbHVlPSIxNDUiPkZydWl0cyZuYnNwOyZuYnNwOygzOTMpPC9vcHRpb24+PG9wdGlvbgpjbGFzcz0ibGV2ZWwtMCIgdmFsdWU9IjE0NCI+QW5pbWFscyZuYnNwOyZuYnNwOygxOTcpPC9vcHRpb24+PG9wdGlvbgpjbGFzcz0ibGV2ZWwtMCIgdmFsdWU9IjE1NSI+QmlyZHMmbmJzcDsmbmJzcDsoNTYpPC9vcHRpb24+PG9wdGlvbgpjbGFzcz0ibGV2ZWwtMCIgdmFsdWU9IjE0OCI+Rmxvd2VycyZuYnNwOyZuYnNwOyg1Nik8L29wdGlvbj48b3B0aW9uCmNsYXNzPSJsZXZlbC0wIiB2YWx1ZT0iMTQzIj5DYXJzJm5ic3A7Jm5ic3A7KDgxMSk8L29wdGlvbj48b3B0aW9uCmNsYXNzPSJsZXZlbC0wIiB2YWx1ZT0iMTU3Ij5WZWhpY2xlcyZuYnNwOyZuYnNwOygzMjEpPC9vcHRpb24+PG9wdGlvbgpjbGFzcz0ibGV2ZWwtMCIgdmFsdWU9IjE1NiI+RWxlY3Ryb25pY3MmbmJzcDsmbmJzcDsoMzA5KTwvb3B0aW9uPjxvcHRpb24KY2xhc3M9ImxldmVsLTAiIHZhbHVlPSIxNDYiPkZvb2QmbmJzcDsmbmJzcDsoMzczKTwvb3B0aW9uPjxvcHRpb24KY2xhc3M9ImxldmVsLTAiIHZhbHVlPSIxNTEiPlBlb3BsZSZuYnNwOyZuYnNwOygzMTUpPC9vcHRpb24+PG9wdGlvbgpjbGFzcz0ibGV2ZWwtMCIgdmFsdWU9IjE0OSI+RmFzaGlvbiZuYnNwOyZuYnNwOygxMTMpPC9vcHRpb24+PG9wdGlvbgpjbGFzcz0ibGV2ZWwtMCIgdmFsdWU9IjE1MiI+RnVybml0dXJlJm5ic3A7Jm5ic3A7KDI2KTwvb3B0aW9uPjxvcHRpb24KY2xhc3M9ImxldmVsLTAiIHZhbHVlPSIxNTQiPkluc2VjdHMmbmJzcDsmbmJzcDsoNDIpPC9vcHRpb24+PG9wdGlvbgpjbGFzcz0ibGV2ZWwtMCIgdmFsdWU9IjE0NyI+TmF0dXJlJm5ic3A7Jm5ic3A7KDE3Myk8L29wdGlvbj48b3B0aW9uCmNsYXNzPSJsZXZlbC0wIiB2YWx1ZT0iMTUzIj5TcG9ydHMmbmJzcDsmbmJzcDsoMTQ4KTwvb3B0aW9uPjxvcHRpb24KY2xhc3M9ImxldmVsLTAiIHZhbHVlPSIxNTAiPk9iamVjdHMmbmJzcDsmbmJzcDsoMSwxMDcpPC9vcHRpb24+PG9wdGlvbgpjbGFzcz0ibGV2ZWwtMCIgdmFsdWU9IjE1OSI+V2VhcG9ucyZuYnNwOyZuYnNwOygxMjcpPC9vcHRpb24+PG9wdGlvbgpjbGFzcz0ibGV2ZWwtMCIgdmFsdWU9IjE1OCI+VG9vbHMmbmJzcDsmbmJzcDsoMTAwKTwvb3B0aW9uPjxvcHRpb24KY2xhc3M9ImxldmVsLTAiIHZhbHVlPSIxMTg1Ij5Mb2dvcyZuYnNwOyZuYnNwOygzODEpPC9vcHRpb24+PG9wdGlvbgpjbGFzcz0ibGV2ZWwtMCIgdmFsdWU9Ijk4Ij5PdGhlcnMmbmJzcDsmbmJzcDsoNTQpPC9vcHRpb24+Cjwvc2VsZWN0Pgo8bm9zY3JpcHQ+PGRpdj48aW5wdXQKdHlwZT0ic3VibWl0IiB2YWx1ZT0iVmlldyIgLz48L2Rpdj48L25vc2NyaXB0PjwvZm9ybT48L2Rpdj48Zm9ybQppZD0ic2VhcmNoZm9ybTIiIGNsYXNzPSJoZWFkZXItc2VhcmNoIiBtZXRob2Q9ImdldCIgYWN0aW9uPSJodHRwczovL3d3dy5wbmdwaXguY29tLyI+PGlucHV0CnBsYWNlaG9sZGVyPSJTZWFyY2ggUE5HIC4uLiIgdHlwZT0idGV4dCIgbmFtZT0icyIgaWQ9InMiIC8+PGlucHV0CnR5cGU9InN1Ym1pdCIgdmFsdWU9IlNlYXJjaCIgY2xhc3M9ImJ1dHRvbmljb24iIC8+PC9mb3JtPjxkaXYKY2xhc3M9ImNsZWFyIj48L2Rpdj48L2Rpdj48ZGl2CmNsYXNzPSJjbGVhciI+PC9kaXY+PC9kaXY+PC9oZWFkZXI+PGRpdgpjbGFzcz0iY2xlYXIiPjwvZGl2PjxkaXYKY2xhc3M9InN1Yi1oZWFkZXIiPjxkaXYKY2xhc3M9IndyYXAtbWlkZGxlIj48Zm9ybQppZD0ic2VhcmNoZm9ybTIiIGNsYXNzPSJoZWFkZXItc2VhcmNoIiBtZXRob2Q9ImdldCIgYWN0aW9uPSJodHRwczovL3d3dy5wbmdwaXguY29tLyI+PGlucHV0CnBsYWNlaG9sZGVyPSJTZWFyY2ggUE5HIC4uLiIgdHlwZT0idGV4dCIgbmFtZT0icyIgaWQ9InMiIC8+PGlucHV0CnR5cGU9InN1Ym1pdCIgdmFsdWU9IlNlYXJjaCIgY2xhc3M9ImJ1dHRvbmljb24iIC8+PC9mb3JtPjxkaXYKY2xhc3M9ImNsZWFyIj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2CmNsYXNzPSJob21lLWZ1bGx3aWR0aCI+PGRpdgpjbGFzcz0id3JhcC1jb250ZW50Ij48ZGl2CmNsYXNzPSJhcmNoaXZlLWhlYWRlciI+PGgzPkVycm9yIDQwNCAtIE5vdCBGb3VuZCA8YnIKLz4gU29ycnksIGJ1dCB5b3UgYXJlIGxvb2tpbmcgZm9yIHNvbWV0aGluZyB0aGF0IGlzbiYjMDM5O3QgaGVyZS48L2gzPjwvZGl2Pjx1bAppZD0iaW5maW5pdGUtYXJ0aWNsZXMiIGNsYXNzPSJncmlkX2xpc3QganMtbWFzb25yeSIgZGF0YS1tYXNvbnJ5LW9wdGlvbnM9J3sgImNvbHVtbldpZHRoIjogMCB9Jz48L3VsPjxkaXYKY2xhc3M9ImNsZWFyIj48L2Rpdj48L2Rpdj48ZGl2CmNsYXNzPSJjbGVhciI+PC9kaXY+PC9kaXY+PGZvb3Rlcj48ZGl2CmNsYXNzPSJzb2NpYWwtc2VjdGlvbiI+PHVsCmNsYXNzPSJmb290ZXItc29jaWFsIj48bGk+PGEKaHJlZj0iaHR0cHM6Ly93d3cuZmFjZWJvb2suY29tL3BuZ3BpeCIgdGFyZ2V0PSJfYmxhbmsiPjxpCmNsYXNzPSJmYSBmYS1mYWNlYm9vayI+PC9pPjwvYT48L2xpPjxsaT48YQpocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL3BuZ3BpeGNvbSIgdGFyZ2V0PSJfYmxhbmsiPjxpCmNsYXNzPSJmYSBmYS10d2l0dGVyIj48L2k+CjwvYT48L2xpPjxsaT48YQpocmVmPSJodHRwczovL3d3dy5waW50ZXJlc3QuY29tL3BuZ3BpeGNvbS8iIHRhcmdldD0iX2JsYW5rIj48aQpjbGFzcz0iZmEgZmEtcGludGVyZXN0Ij48L2k+PC9hPjwvbGk+PGxpPjxhCmhyZWY9IiMiPjxpCmNsYXNzPSJmYSBmYS1nb29nbGUtcGx1cyI+PC9pPjwvYT48L2xpPjxsaT48YQpocmVmPSIjIj48aQpjbGFzcz0iZmEgZmEteW91dHViZSI+PC9pPjwvYT48L2xpPjwvdWw+PC9kaXY+PGRpdgpjbGFzcz0id3JhcC1mb290ZXIiPjxkaXYKY2xhc3M9ImNvcHlyaWdodCI+CkNvcHlyaWdodCDCqSAyMDE4IFBuZ1BpeCA8YQpocmVmPSIjIj5BYm91dDwvYT4gfCA8YQpocmVmPSIjIj5MaWNlbnNlPC9hPiB8IDxhCmhyZWY9IiMiPlRlcm1zIG9mIFNlcnZpY2U8L2E+IHwgPGEKaHJlZj0iIyI+RE1DQSBDb3B5cmlnaHQgUG9saWN5PC9hPjwvZGl2PjwvZGl2PjxwCmlkPSJiYWNrLXRvcCI+PGEKaHJlZj0iI3RvcCI+PHNwYW4+PC9zcGFuPjwvYT48L3A+CjwvZm9vdGVyPiA8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+dmFyIGpxdWVyeWNzc21lbnU9e2ZhZGVzZXR0aW5nczp7b3ZlcmR1cmF0aW9uOjAsb3V0ZHVyYXRpb246MTAwfSxidWlsZG1lbnU6ZnVuY3Rpb24oYixhKXtqUXVlcnkoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKGUpe3ZhciBjPWUoIiMiK2IrIj51bCIpO3ZhciBkPWMuZmluZCgidWwiKS5wYXJlbnQoKTtkLmVhY2goZnVuY3Rpb24oZyl7dmFyIGg9ZSh0aGlzKTt2YXIgZj1lKHRoaXMpLmZpbmQoInVsOmVxKDApIik7dGhpcy5fZGltZW5zaW9ucz17dzp0aGlzLm9mZnNldFdpZHRoLGg6dGhpcy5vZmZzZXRIZWlnaHQsc3VidWx3OmYub3V0ZXJXaWR0aCgpLHN1YnVsaDpmLm91dGVySGVpZ2h0KCl9O3RoaXMuaXN0b3BoZWFkZXI9aC5wYXJlbnRzKCJ1bCIpLmxlbmd0aD09MT90cnVlOmZhbHNlO2YuY3NzKHt0b3A6dGhpcy5pc3RvcGhlYWRlcj90aGlzLl9kaW1lbnNpb25zLmgrInB4IjowfSk7aC5jaGlsZHJlbigiYTplcSgwKSIpLmNzcyh0aGlzLmlzdG9waGVhZGVyP3twYWRkaW5nUmlnaHQ6YS5kb3duWzJdfTp7fSkuYXBwZW5kKCc8aW1nIHNyYz0iJysodGhpcy5pc3RvcGhlYWRlcj9hLmRvd25bMV06YS5yaWdodFsxXSkrJyIgY2xhc3M9IicrKHRoaXMuaXN0b3BoZWFkZXI/YS5kb3duWzBdOmEucmlnaHRbMF0pKyciIHN0eWxlPSJib3JkZXI6MDsiIC8+Jyk7aC5ob3ZlcihmdW5jdGlvbihqKXt2YXIgaT1lKHRoaXMpLmNoaWxkcmVuKCJ1bDplcSgwKSIpO3RoaXMuX29mZnNldHM9e2xlZnQ6ZSh0aGlzKS5vZmZzZXQoKS5sZWZ0LHRvcDplKHRoaXMpLm9mZnNldCgpLnRvcH07dmFyIGs9dGhpcy5pc3RvcGhlYWRlcj8wOnRoaXMuX2RpbWVuc2lvbnMudztrPSh0aGlzLl9vZmZzZXRzLmxlZnQrayt0aGlzLl9kaW1lbnNpb25zLnN1YnVsdz5lKHdpbmRvdykud2lkdGgoKSk/KHRoaXMuaXN0b3BoZWFkZXI/LXRoaXMuX2RpbWVuc2lvbnMuc3VidWx3K3RoaXMuX2RpbWVuc2lvbnMudzotdGhpcy5fZGltZW5zaW9ucy53KTprO2kuY3NzKHtsZWZ0OmsrInB4In0pLmZhZGVJbihqcXVlcnljc3NtZW51LmZhZGVzZXR0aW5ncy5vdmVyZHVyYXRpb24pfSxmdW5jdGlvbihpKXtlKHRoaXMpLmNoaWxkcmVuKCJ1bDplcSgwKSIpLmZhZGVPdXQoanF1ZXJ5Y3NzbWVudS5mYWRlc2V0dGluZ3Mub3V0ZHVyYXRpb24pfSl9KTtjLmZpbmQoInVsIikuY3NzKHtkaXNwbGF5OiJub25lIix2aXNpYmlsaXR5OiJ2aXNpYmxlIn0pfSl9fTt2YXIgYXJyb3dpbWFnZXM9e2Rvd246Wydkb3duYXJyb3djbGFzcycsJ2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC90aGVtZXMvcG5ncGl4L2ltYWdlcy9tZW51L2Fycm93LWRvd24ucG5nJ10scmlnaHQ6WydyaWdodGFycm93Y2xhc3MnLCdodHRwczovL3d3dy5wbmdwaXguY29tL3dwLWNvbnRlbnQvdGhlbWVzL3BuZ3BpeC9pbWFnZXMvbWVudS9hcnJvdy1yaWdodC5wbmcnXX07anF1ZXJ5Y3NzbWVudS5idWlsZG1lbnUoIm15anF1ZXJ5bWVudSIsYXJyb3dpbWFnZXMpO2pxdWVyeWNzc21lbnUuYnVpbGRtZW51KCJteWpxdWVyeW1lbnUtY2F0IixhcnJvd2ltYWdlcyk7PC9zY3JpcHQ+IDxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij5qUXVlcnkoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCQpeyRrd21Gb3JjZURvd25sb2FkPSQoImJvZHkgYS5rd20tZm9yY2UtZG9ud2xvYWQiKTska3dtRm9yY2VEb3dubG9hZC5lYWNoKGZ1bmN0aW9uKGluZGV4KXt2YXIgb2xkSHJlZj0kKHRoaXMpLmRhdGEoImZvcmNlZG93bmxvYWQiKTskKHRoaXMpLnByb3AoImhyZWYiLCJodHRwczovL3d3dy5wbmdwaXguY29tL2Rvd25sb2FkLyIrb2xkSHJlZik7fSk7fSk7PC9zY3JpcHQ+PHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij52YXIga3BnX2NlbGw9Ik4iO3ZhciBrcGdfbnJjaV9pbWFnZT0iaHR0cDovL3d3dy5wbmdwaXguY29tL3dwLWNvbnRlbnQvcGx1Z2lucy9uby1yaWdodC1jbGljay1pbWFnZXMtcGx1Z2luL25vdC5naWYiO3ZhciBrcGdfbnJjaV9leHRyYT0iTiI7dmFyIGtwZ19ucmNpX2RyYWc9IlkiOzwvc2NyaXB0PiA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cDovL3d3dy5wbmdwaXguY29tL3dwLWNvbnRlbnQvcGx1Z2lucy9uby1yaWdodC1jbGljay1pbWFnZXMtcGx1Z2luL25vLXJpZ2h0LWNsaWNrLWltYWdlcy5qcyI+PC9zY3JpcHQ+IDxzY3JpcHQ+alF1ZXJ5KGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpe2pRdWVyeS5wb3N0KCdodHRwczovL3d3dy5wbmdwaXguY29tP2dhX2FjdGlvbj1nb29nbGVhbmFseXRpY3NfZ2V0X3NjcmlwdCcse2FjdGlvbjonZ29vZ2xlYW5hbHl0aWNzX2dldF9zY3JpcHQnfSxmdW5jdGlvbihyZXNwb25zZSl7dmFyIEY9bmV3IEZ1bmN0aW9uKHJlc3BvbnNlKTtyZXR1cm4oRigpKTt9KTt9KTs8L3NjcmlwdD48ZGl2CnN0eWxlPSJkaXNwbGF5Om5vbmUiPjxkaXYKaWQ9ImFydmxiZGF0YSIgc3R5bGU9Im92ZXJmbG93OnZpc2libGU7d2lkdGg6NDAwcHg7aGVpZ2h0OjI1MHB4OyI+PGRpdgphbGxvd3RyYW5zcGFyZW5jeT0idHJ1ZSIgc3R5bGU9Im92ZXJmbG93OmhpZGRlbjt3aWR0aDo0MDBweDtoZWlnaHQ6MjUwcHg7IiBjbGFzcz0iZmItcGFnZSIKZGF0YS1ocmVmPSJodHRwczovL3d3dy5mYWNlYm9vay5jb20vcG5ncGl4IgpkYXRhLXdpZHRoPSI0MDAiCmRhdGEtaGVpZ2h0PSIyNTAiCmRhdGEtc21hbGwtaGVhZGVyPSJmYWxzZSIKZGF0YS1hZGFwdC1jb250YWluZXItd2lkdGg9ImZhbHNlIgpkYXRhLWhpZGUtY292ZXI9InRydWUiCmRhdGEtc2hvdy1mYWNlcGlsZT0idHJ1ZSIKZGF0YS1zaG93LXBvc3RzPSJmYWxzZSI+PC9kaXY+PC9kaXY+PC9kaXY+IDxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0JyBzcmM9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC90aGVtZXMvcG5ncGl4L293bC1jYXJvdXNlbC9vd2wuY2Fyb3VzZWwubWluLmpzP3Zlcj00LjkuNCc+PC9zY3JpcHQ+IDxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0JyBzcmM9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC90aGVtZXMvcG5ncGl4L2pzL2pxdWVyeS5tYWluLmpzP3Zlcj00LjkuNCc+PC9zY3JpcHQ+IDxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0JyBzcmM9J2h0dHBzOi8vd3d3LnBuZ3BpeC5jb20vd3AtY29udGVudC90aGVtZXMvcG5ncGl4L2pzL2N1c3RvbS5qcz92ZXI9NC45LjQnPjwvc2NyaXB0PiA8c2NyaXB0IHR5cGU9J3RleHQvamF2YXNjcmlwdCcgc3JjPSdodHRwczovL3d3dy5wbmdwaXguY29tL3dwLWluY2x1ZGVzL2pzL3dwLWVtYmVkLm1pbi5qcz92ZXI9NC45LjQnPjwvc2NyaXB0PiA8L2JvZHk+PC9odG1sPgo8IS0tCioqKiBUaGlzIHNpdGUgcnVucyBXUCBTdXBlciBNaW5pZnkgcGx1Z2luIHYxLjUuMSAtIGh0dHA6Ly93b3JkcHJlc3Mub3JnL3BsdWdpbnMvd3Atc3VwZXItbWluaWZ5ICoqKgoqKiogVG90YWwgc2l6ZSBzYXZlZDogMTYuMTg0JSB8IFNpemUgYmVmb3JlIGNvbXByZXNzaW9uOiAyMDY5OSBieXRlcyB8IFNpemUgYWZ0ZXIgY29tcHJlc3Npb246IDE3MzQ5IGJ5dGVzLiAqKioKLS0+ + mediatype: image/png + labels: + alm-owner-ibmblockcsi: ibmblockcsioperator + operated-by: ibmblockcsioperator + selector: + matchLabels: + alm-owner-ibmblockcsi: ibmblockcsioperator + operated-by: ibmblockcsioperator + installModes: + - type: OwnNamespace + supported: true + - type: SingleNamespace + supported: true + - type: MultiNamespace + supported: false + - type: AllNamespaces + supported: false + customresourcedefinitions: + owned: + - name: ibmblockcsis.csi.ibm.com + version: v1 + group: csi.ibm.com + kind: IBMBlockCSI + displayName: "IBM block storage CSI driver" + description: "Represents an block storage CSI driver" + resources: + - kind: ServiceAccount + name: '' + version: v1 + - kind: StatefulSet + name: '' + version: apps/v1 + - kind: DaemonSet + name: '' + version: apps/v1 + specDescriptors: + - description: Controller Image Repository. + displayName: Controller Image Repository + path: controller.repository + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:text' + - description: Controller Image Tag. + displayName: Controller Image Tag + path: controller.tag + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:text' + - description: Node Image Repository. + displayName: Node Image Repository + path: node.repository + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:text' + - description: Node Image Tag. + displayName: Node Image Tag + path: node.tag + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:text' + statusDescriptors: + - description: The current status of the driver. + displayName: Status + path: phase + x-descriptors: + - 'urn:alm:descriptor:io.kubernetes.phase' + - description: Is the controller ready? + displayName: Controller Ready + path: controllerReady + x-descriptors: + - 'urn:alm:descriptor:text' + - description: Is the node ready? + displayName: Node Ready + path: nodeReady + x-descriptors: + - 'urn:alm:descriptor:text' + - description: The current version of the driver. + displayName: Version + path: version + install: + strategy: deployment + spec: + clusterPermissions: + - serviceAccountName: ibm-block-csi-operator + rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - create + - delete + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - get + - list + - watch + - update + - apiGroups: + - "" + resources: + - persistentvolumes + verbs: + - get + - list + - watch + - update + - create + - delete + - patch + - apiGroups: + - "" + resources: + - events + verbs: + - '*' + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - deployments + - daemonsets + - statefulsets + verbs: + - get + - list + - watch + - update + - create + - delete + - apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - delete + - get + - watch + - list + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + - clusterrolebindings + verbs: + - create + - delete + - get + - watch + - list + - apiGroups: + - storage.k8s.io + resources: + - volumeattachments + verbs: + - get + - list + - watch + - update + - patch + - apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - apps + resourceNames: + - ibm-block-csi-operator + resources: + - deployments/finalizers + verbs: + - update + - apiGroups: + - storage.k8s.io + resources: + - csidrivers + verbs: + - create + - delete + - get + - watch + - list + - apiGroups: + - storage.k8s.io + resources: + - csinodes + verbs: + - get + - list + - watch + - apiGroups: + - security.openshift.io + resourceNames: + - anyuid + - privileged + resources: + - securitycontextconstraints + verbs: + - use + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - create + - list + - watch + - delete + - apiGroups: + - csi.ibm.com + resources: + - '*' + verbs: + - '*' + deployments: + - name: ibm-block-csi-operator + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: ibm-block-csi-operator + template: + metadata: + labels: + app.kubernetes.io/name: ibm-block-csi-operator + spec: + serviceAccountName: ibm-block-csi-operator + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + containers: + - name: ibm-block-csi-operator + resources: + requests: + memory: 50Mi + cpu: 50m + limits: + memory: 100Mi + cpu: 100m + readinessProbe: + exec: + command: ["./health_check.sh"] + initialDelaySeconds: 3 + periodSeconds: 1 + livenessProbe: + exec: + command: ["./health_check.sh"] + initialDelaySeconds: 10 + periodSeconds: 30 + securityContext: + capabilities: + drop: + - ALL + image: registry.connect.redhat.com/ibm/ibm-block-csi-operator:1.1.0 + imagePullPolicy: IfNotPresent + command: + - ibm-block-csi-operator + env: + - name: WATCH_NAMESPACE + value: "" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "ibm-block-csi-operator" diff --git a/deploy/olm-catalog/ibm-block-csi-operator/1.0.0/ibm-block-csi-operator.package.yaml b/deploy/olm-catalog/ibm-block-csi-operator/ibm-block-csi-operator.package.yaml similarity index 65% rename from deploy/olm-catalog/ibm-block-csi-operator/1.0.0/ibm-block-csi-operator.package.yaml rename to deploy/olm-catalog/ibm-block-csi-operator/ibm-block-csi-operator.package.yaml index 10fb50cae..526960214 100644 --- a/deploy/olm-catalog/ibm-block-csi-operator/1.0.0/ibm-block-csi-operator.package.yaml +++ b/deploy/olm-catalog/ibm-block-csi-operator/ibm-block-csi-operator.package.yaml @@ -1,5 +1,5 @@ packageName: ibm-block-csi-operator channels: - name: stable - currentCSV: ibm-block-csi-operator.v1.0.0 + currentCSV: ibm-block-csi-operator.v1.1.0 defaultChannel: stable diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 88d017281..b16bf52d3 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -25,7 +25,7 @@ spec: annotations: productName: ibm-block-csi-operator productID: ibm-block-csi-operator - productVersion: "1.0.0" + productVersion: "1.1.0" spec: serviceAccountName: ibm-block-csi-operator affinity: @@ -60,7 +60,7 @@ spec: capabilities: drop: - ALL - image: ibmcom/ibm-block-csi-operator:1.0.0 + image: ibmcom/ibm-block-csi-operator:1.1.0 imagePullPolicy: IfNotPresent command: - ibm-block-csi-operator diff --git a/deploy/role.yaml b/deploy/role.yaml index 5a560fd14..0139ccd8c 100644 --- a/deploy/role.yaml +++ b/deploy/role.yaml @@ -51,6 +51,7 @@ rules: - update - create - delete + - patch - apiGroups: - "" resources: @@ -108,6 +109,7 @@ rules: - list - watch - update + - patch - apiGroups: - storage.k8s.io resources: @@ -149,6 +151,15 @@ rules: - get - list - watch +- apiGroups: + - security.openshift.io + resourceNames: + - anyuid + - privileged + resources: + - securitycontextconstraints + verbs: + - use - apiGroups: - apiextensions.k8s.io resources: diff --git a/hack/update-crds.sh b/hack/update-crds.sh new file mode 100755 index 000000000..272bbb4ea --- /dev/null +++ b/hack/update-crds.sh @@ -0,0 +1,28 @@ +#!/bin/bash -xe + +# +# Copyright 2019 IBM Corp. +# +# 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. +# + +# Run operator-sdk generate k8s and operator-sdk generate openapi to update code after crd changes. + +if ! [ -x "$(command -v operator-sdk)" ]; then + echo 'Error: operator-sdk is not installed.' >&2 + exit 1 +fi + +operator-sdk generate k8s + +operator-sdk generate openapi diff --git a/hack/update-installer.sh b/hack/update-installer.sh index 0fa73403d..e54153197 100755 --- a/hack/update-installer.sh +++ b/hack/update-installer.sh @@ -41,7 +41,7 @@ function contains() echo "generate operator installer" -printf "# Code generated by update-copyright.sh. DO NOT EDIT.\n\n" > $TARGET_FILE +printf "# Code generated by $(basename $0). DO NOT EDIT.\n\n" > $TARGET_FILE for file_name in $(ls $CRD_PATH) do diff --git a/pkg/config/resources.go b/pkg/config/resources.go index 087915fbb..2bee109bb 100644 --- a/pkg/config/resources.go +++ b/pkg/config/resources.go @@ -37,6 +37,10 @@ const ( ExternalAttacherClusterRoleBinding ResourceName = "external-attacher-clusterrolebinding" ExternalSnapshotterClusterRole ResourceName = "external-snapshotter-clusterrole" ExternalSnapshotterClusterRoleBinding ResourceName = "external-snapshotter-clusterrolebinding" + CSIControllerSCCClusterRole ResourceName = "csi-controller-scc-clusterrole" + CSIControllerSCCClusterRoleBinding ResourceName = "csi-controller-scc-clusterrolebinding" + CSINodeSCCClusterRole ResourceName = "csi-node-scc-clusterrole" + CSINodeSCCClusterRoleBinding ResourceName = "csi-node-scc-clusterrolebinding" ) // GetNameForResource returns the name of a resource for a CSI driver diff --git a/pkg/config/settings.go b/pkg/config/settings.go index 0c8115ad5..d473da43a 100644 --- a/pkg/config/settings.go +++ b/pkg/config/settings.go @@ -22,8 +22,8 @@ const ( CSIAttacherImage = "quay.io/k8scsi/csi-attacher:v1.2.1" CSILivenessProbeImage = "quay.io/k8scsi/livenessprobe:v1.1.0" - ControllerTag = "1.0.0" - NodeTag = "1.0.0" + ControllerTag = "1.1.0" + NodeTag = "1.1.0" NodeAgentTag = "1.0.0" DefaultNamespace = "kube-system" diff --git a/pkg/controller/ibmblockcsi/ibmblockcsi_controller.go b/pkg/controller/ibmblockcsi/ibmblockcsi_controller.go index 9644707ce..22461f9bd 100644 --- a/pkg/controller/ibmblockcsi/ibmblockcsi_controller.go +++ b/pkg/controller/ibmblockcsi/ibmblockcsi_controller.go @@ -21,6 +21,7 @@ import ( "fmt" "os" "reflect" + "strings" "time" csiv1 "github.com/IBM/ibm-block-csi-operator/pkg/apis/csi/v1" @@ -79,7 +80,14 @@ func getServerVersion() (string, error) { return "", err } - return kubeutil.ServerVersion(kubeClient.Discovery()) + serverVersion, err := kubeutil.ServerVersion(kubeClient.Discovery()) + if err != nil { + return serverVersion, err + } + if strings.HasSuffix(serverVersion, "+") { + serverVersion = strings.TrimSuffix(serverVersion, "+") + } + return serverVersion, nil } // newReconciler returns a new reconcile.Reconciler @@ -333,11 +341,15 @@ func (r *ReconcileIBMBlockCSI) reconcileClusterRole(instance *ibmblockcsi.IBMBlo externalProvisioner := instance.GenerateExternalProvisionerClusterRole() externalAttacher := instance.GenerateExternalAttacherClusterRole() + controllerSCC := instance.GenerateSCCForControllerClusterRole() + nodeSCC := instance.GenerateSCCForNodeClusterRole() //externalSnapshotter := instance.GenerateExternalSnapshotterClusterRole() for _, cr := range []*rbacv1.ClusterRole{ externalProvisioner, externalAttacher, + controllerSCC, + nodeSCC, //externalSnapshotter, } { if err := controllerutil.SetControllerReference(instance.Unwrap(), cr, r.scheme); err != nil { @@ -371,11 +383,15 @@ func (r *ReconcileIBMBlockCSI) reconcileClusterRoleBinding(instance *ibmblockcsi externalProvisioner := instance.GenerateExternalProvisionerClusterRoleBinding() externalAttacher := instance.GenerateExternalAttacherClusterRoleBinding() + controllerSCC := instance.GenerateSCCForControllerClusterRoleBinding() + nodeSCC := instance.GenerateSCCForNodeClusterRoleBinding() //externalSnapshotter := instance.GenerateExternalSnapshotterClusterRoleBinding() for _, crb := range []*rbacv1.ClusterRoleBinding{ externalProvisioner, externalAttacher, + controllerSCC, + nodeSCC, //externalSnapshotter, } { if err := controllerutil.SetControllerReference(instance.Unwrap(), crb, r.scheme); err != nil { diff --git a/pkg/controller/ibmblockcsi/syncer/csi_controller.go b/pkg/controller/ibmblockcsi/syncer/csi_controller.go index f8d9b466d..532441ae3 100644 --- a/pkg/controller/ibmblockcsi/syncer/csi_controller.go +++ b/pkg/controller/ibmblockcsi/syncer/csi_controller.go @@ -134,14 +134,16 @@ func (s *csiControllerSyncer) ensureContainersSpec() []corev1.Container { // csi provisioner sidecar provisioner := s.ensureContainer(provisionerContainerName, s.getCSIProvisionerImage(), - []string{"--csi-address=$(ADDRESS)", "--v=5"}, + // TODO: make timeout configurable + []string{"--csi-address=$(ADDRESS)", "--v=5", "--timeout=30s"}, ) provisioner.ImagePullPolicy = s.getCSIProvisionerPullPolicy() // csi attacher sidecar attacher := s.ensureContainer(attacherContainerName, s.getCSIAttacherImage(), - []string{"--csi-address=$(ADDRESS)", "--v=5"}, + // TODO: make timeout configurable + []string{"--csi-address=$(ADDRESS)", "--v=5", "--timeout=30s"}, ) attacher.ImagePullPolicy = s.getCSIAttacherPullPolicy() diff --git a/pkg/controller/ibmblockcsi/syncer/csi_node.go b/pkg/controller/ibmblockcsi/syncer/csi_node.go index f7b8aabc6..3eb7db296 100644 --- a/pkg/controller/ibmblockcsi/syncer/csi_node.go +++ b/pkg/controller/ibmblockcsi/syncer/csi_node.go @@ -97,6 +97,7 @@ func (s *csiNodeSyncer) ensurePodSpec() corev1.PodSpec { Containers: s.ensureContainersSpec(), Volumes: s.ensureVolumes(), HostIPC: true, + HostNetwork: true, ServiceAccountName: config.GetNameForResource(config.CSINodeServiceAccount, s.driver.Name), Affinity: s.driver.Spec.Node.Affinity, Tolerations: s.driver.Spec.Node.Tolerations, @@ -266,6 +267,14 @@ func (s *csiNodeSyncer) getVolumeMountsFor(name string) []corev1.VolumeMount { MountPath: "/host", MountPropagation: &mountPropagationB, }, + { + Name: "lib-modules", + MountPath: "/lib/modules", + }, + { + Name: "iscsi", + MountPath: "/etc/iscsi", + }, } case nodeDriverRegistrarContainerName: @@ -299,6 +308,8 @@ func (s *csiNodeSyncer) ensureVolumes() []corev1.Volume { ensureVolume("device-dir", ensureHostPathVolumeSource("/dev", "Directory")), ensureVolume("sys-dir", ensureHostPathVolumeSource("/sys", "Directory")), ensureVolume("host-dir", ensureHostPathVolumeSource("/", "Directory")), + ensureVolume("lib-modules", ensureHostPathVolumeSource("/lib/modules", "Directory")), + ensureVolume("iscsi", ensureHostPathVolumeSource("/etc/iscsi", "Directory")), } } diff --git a/pkg/internal/ibmblockcsi/static_resource_generator.go b/pkg/internal/ibmblockcsi/static_resource_generator.go index f9aa2d36b..5f0646337 100644 --- a/pkg/internal/ibmblockcsi/static_resource_generator.go +++ b/pkg/internal/ibmblockcsi/static_resource_generator.go @@ -157,7 +157,7 @@ func (c *IBMBlockCSI) GenerateExternalAttacherClusterRole() *rbacv1.ClusterRole { APIGroups: []string{""}, Resources: []string{"persistentvolumes"}, - Verbs: []string{"get", "list", "watch", "update"}, + Verbs: []string{"get", "list", "watch", "update", "patch"}, }, { APIGroups: []string{c.GetCSIAPIGroup()}, @@ -172,7 +172,7 @@ func (c *IBMBlockCSI) GenerateExternalAttacherClusterRole() *rbacv1.ClusterRole { APIGroups: []string{"storage.k8s.io"}, Resources: []string{"volumeattachments"}, - Verbs: []string{"get", "list", "watch", "update"}, + Verbs: []string{"get", "list", "watch", "update", "patch"}, }, }, } @@ -273,6 +273,78 @@ func (c *IBMBlockCSI) GenerateExternalSnapshotterClusterRoleBinding() *rbacv1.Cl } } +func (c *IBMBlockCSI) GenerateSCCForControllerClusterRole() *rbacv1.ClusterRole { + return &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.GetNameForResource(config.CSIControllerSCCClusterRole, c.Name), + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"security.openshift.io"}, + Resources: []string{"securitycontextconstraints"}, + ResourceNames: []string{"anyuid"}, + Verbs: []string{"use"}, + }, + }, + } +} + +func (c *IBMBlockCSI) GenerateSCCForControllerClusterRoleBinding() *rbacv1.ClusterRoleBinding { + return &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.GetNameForResource(config.CSIControllerSCCClusterRoleBinding, c.Name), + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: config.GetNameForResource(config.CSIControllerServiceAccount, c.Name), + Namespace: c.Namespace, + }, + }, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: config.GetNameForResource(config.CSIControllerSCCClusterRole, c.Name), + APIGroup: "rbac.authorization.k8s.io", + }, + } +} + +func (c *IBMBlockCSI) GenerateSCCForNodeClusterRole() *rbacv1.ClusterRole { + return &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.GetNameForResource(config.CSINodeSCCClusterRole, c.Name), + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"security.openshift.io"}, + Resources: []string{"securitycontextconstraints"}, + ResourceNames: []string{"privileged"}, + Verbs: []string{"use"}, + }, + }, + } +} + +func (c *IBMBlockCSI) GenerateSCCForNodeClusterRoleBinding() *rbacv1.ClusterRoleBinding { + return &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.GetNameForResource(config.CSINodeSCCClusterRoleBinding, c.Name), + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: config.GetNameForResource(config.CSINodeServiceAccount, c.Name), + Namespace: c.Namespace, + }, + }, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: config.GetNameForResource(config.CSINodeSCCClusterRole, c.Name), + APIGroup: "rbac.authorization.k8s.io", + }, + } +} + func (c *IBMBlockCSI) GetCSIAPIGroup() string { if c.ServerVersion == "1.13" { return "csi.storage.k8s.io" diff --git a/version/version.go b/version/version.go index 247c1b1d3..144303d5e 100644 --- a/version/version.go +++ b/version/version.go @@ -17,6 +17,6 @@ package version var ( - Version = "1.0.0" - DriverVersion = "1.0.0" + Version = "1.1.0" + DriverVersion = "1.1.0" )