-
Notifications
You must be signed in to change notification settings - Fork 58
Allow remote-config to be generated from a standby #843
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
souravbiswassanto
wants to merge
1
commit into
master
Choose a base branch
from
remote-config-skip-user-creation
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| /* | ||
| Copyright AppsCode Inc. and Contributors | ||
|
|
||
| Licensed under the AppsCode Community License 1.0.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|
|
||
| https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| */ | ||
|
|
||
| package common | ||
|
|
||
| // OptionFunc tunes how a per-engine Opts value is built. | ||
| type OptionFunc func(*optionConfig) | ||
|
|
||
| type optionConfig struct { | ||
| skipReadinessCheck bool | ||
| } | ||
|
|
||
| // SkipReadinessCheck drops the `status.phase == Ready` gate on the database CR. | ||
| // Commands that only read the CR to render manifests do not need a healthy | ||
| // database, and refusing to run against a degraded source is actively unhelpful | ||
| // for disaster-recovery workflows, where the source being unhealthy is the | ||
| // whole reason the command is being run. | ||
| func SkipReadinessCheck() OptionFunc { | ||
| return func(cfg *optionConfig) { | ||
| cfg.skipReadinessCheck = true | ||
| } | ||
| } | ||
|
|
||
| func buildOptionConfig(opts []OptionFunc) optionConfig { | ||
| var cfg optionConfig | ||
| for _, opt := range opts { | ||
| opt(&cfg) | ||
| } | ||
| return cfg | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| /* | ||
| Copyright AppsCode Inc. and Contributors | ||
|
|
||
| Licensed under the AppsCode Community License 1.0.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|
|
||
| https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| */ | ||
|
|
||
| package remote_replica | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
|
|
||
| "kubedb.dev/apimachinery/apis/kubedb" | ||
|
|
||
| core "k8s.io/api/core/v1" | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| "k8s.io/apimachinery/pkg/labels" | ||
| "k8s.io/client-go/kubernetes" | ||
| ) | ||
|
|
||
| // Containers holding the database server itself, the ones a client query has to | ||
| // be exec-ed into. | ||
| const ( | ||
| PostgresContainerName = "postgres" | ||
| MySQLContainerName = "mysql" | ||
| ) | ||
|
|
||
| // pickDBPod returns a running database pod to exec into. | ||
| // | ||
| // primaryOnly is set when the caller intends to run DDL. CREATE ROLE / ALTER | ||
| // ROLE / GRANT write to the shared catalog, and a hot standby rejects them with | ||
| // "cannot execute ... in a read-only transaction", so only a pod labelled | ||
| // kubedb.com/role=primary qualifies. Read-only catalog queries run fine on any | ||
| // member, so verification passes primaryOnly=false and merely prefers the | ||
| // primary when one happens to be labelled. | ||
| func pickDBPod(client kubernetes.Interface, ns string, selector map[string]string, container string, primaryOnly bool) (*core.Pod, error) { | ||
| pods, err := client.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{ | ||
| LabelSelector: labels.Set(selector).String(), | ||
| }) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| pod, err := selectPod(pods.Items, container, primaryOnly) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("in namespace %s: %v", ns, err) | ||
| } | ||
| return pod, nil | ||
| } | ||
|
|
||
| // selectPod holds the choice itself, kept free of any client so it can be | ||
| // exercised directly. Only pods that actually carry `container` are eligible: a | ||
| // KubeDB cluster runs helper pods under the same offshoot labels - the Postgres | ||
| // arbiter, for one, runs pg-coordinator alone - and exec-ing a database query | ||
| // into those fails in a way that is hard to read. | ||
| func selectPod(pods []core.Pod, container string, primaryOnly bool) (*core.Pod, error) { | ||
| var usable []core.Pod | ||
| for i := range pods { | ||
| if pods[i].Status.Phase == core.PodRunning && hasRunningContainer(&pods[i], container) { | ||
| usable = append(usable, pods[i]) | ||
| } | ||
| } | ||
| if len(usable) == 0 { | ||
| // Reported explicitly: an empty list used to be swallowed and treated as | ||
| // success, which produced a config for a user that was never created. | ||
| return nil, fmt.Errorf("none of the %d database pod(s) has a running %q container", len(pods), container) | ||
| } | ||
|
|
||
| for i := range usable { | ||
| if usable[i].Labels[kubedb.LabelRole] == kubedb.DatabasePodPrimary { | ||
| return &usable[i], nil | ||
| } | ||
| } | ||
| if primaryOnly { | ||
| return nil, fmt.Errorf("no pod is labelled %s=%s, so there is no writable primary to run DDL against", | ||
| kubedb.LabelRole, kubedb.DatabasePodPrimary) | ||
| } | ||
| return &usable[0], nil | ||
| } | ||
|
|
||
| func hasRunningContainer(pod *core.Pod, container string) bool { | ||
| for _, cs := range pod.Status.ContainerStatuses { | ||
| if cs.Name == container { | ||
| return cs.State.Running != nil | ||
| } | ||
| } | ||
| return false | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🛡️ Analyzed with Security Review | 🟠 Major | ⚡ Quick win
Injection
Reachability: External
Exploitability: Moderate
CWE: CWE-78 — Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Remove the shell interpolation from MySQL verification.
namecomes from--userand is inserted into abash -ccommand. Shell expressions such as$(...)are evaluated even though the value appears between SQL single quotes.opts.Passcan also break the shell command.Invoke
envandmysqlwith separate arguments. Encode or parameterizenameseparately for SQL.🧰 Tools
🪛 GitHub Actions: CI / 0_Build.txt
[error] 266-270: Generated formatting is out of date. Run 'make gen fmt' to apply the required gofmt changes.
🪛 GitHub Actions: CI / Build
[error] 266-269: Generated formatting is out of date. gofmt modified this file; run 'make gen fmt' before committing.
🪛 OpenGrep (1.29.0)
[ERROR] 270-270: Dynamic command passed to exec.Command with a shell invocation. Pass arguments directly to exec.Command without a shell wrapper.
(coderabbit.command-injection.go-exec-command)
🤖 Prompt for AI Agents