How to match a particular string using regex? - regex

Hi i have string like below,
apiVersion: v1
clusters:
- cluster: <------------------------ this is one cluster
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ
server: https://api.someaddress
name: https://api.anotheraddress
- second_cluster: <------------------------ this is second cluster
certificate-authority-data: LS0tLS1
server: https://api.someaddress
name: https://api.
contexts:
- context: <------------------------ this is one context
cluster: https://api.another1address
namespace: name1
user: user1
name: somename
- another_context: <------------------------ this is second context
cluster: https://api.anotheraddress
namespace: esm2
user: admin
name: somename1
current-context: some-context
kind: somekind
preferences: {}
users:
- name: user-admin
user:
token: eyJhb
how can i check if the there is more than one cluster under clusters and more than one context under contexts using regex.
i have tried something like below
var matchServer = new RegExp(/- cluster:\n[A-Za-z0-9\- :]*\n[ ]+server: ([A-Za-z:.//]*)/, "gi").exec(s);
const namespace = s.match(/contexts:\n- context:\n[A-Za-z0-9\- :.//]*\n[ ]+namespace: ([A-Za-z0-9]*)/i);
but this gives server and namespace also only one occurrence is returned.
i want to get the number of matched string "cluster" under clusters and context under contexts.
could someone help me with this. i am new to programming. thanks.
what i have tried?
i have tried regex to match "context" "another_context" under contexts. but it matches only "context"
contexts:\n-.*context:+
could someone help me understand why it doesnt match the another_context string
updated question:
with the regex
const matchServer = result.match(/- [a-z_]cluster:[A-Za-z0-9- :\n][ ]+server: ([A-Za-z0-9:.//]*)/gi);
this returns null for below string although there is server under cluster.
apiVersion: v1
clusters:
- cluster:
certificate-authority-data:
LS0tLS1CRUd
server: https://api.sandbox1.lab.fi.eu.ericsson.se
name: https://api.sandbox1.lab.fi.eu.ericsson.se
contexts:
- context:
cluster: https://api.sandbox1.lab.fi.eu.ericsson.se
namespace: esm1
user: esm-esm1-ci-namespace-admin
name: esm-context
current-context: esm-context
kind: Config
preferences: {}
users:
- name: esm-esm1-ci-namespace-admin
user:
token:
eyJhbGc
why doesnt the above regex work for this string. could someone help me with this. thanks.

<html>
<head>
<script>
var s = `apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ
server: https://api.someaddress1
name: https://api.anotheraddress
- second_cluster:
certificate-authority-data: LS0tLS1
server: https://api.someaddress2
name: https://api.
contexts:
- context:
cluster: https://api.another1address
namespace: name1
user: user1
name: somename
- another_context:
cluster: https://api.anotheraddress
namespace: esm2
user: admin
name: somename1
current-context: some-context
kind: somekind
preferences: {}
users:
- name: user-admin
user:
token: eyJhb`;
var matchServer = s.match(/- [a-z_]*cluster:/gi)
var matchNamespace = s.match(/- [a-z_]*context:/gi)
document.write(matchServer.length + ' servers <br/>')
for(i=0;i<matchServer.length;i++)
document.write(matchServer[i] + '<br/>')
document.write(matchNamespace.length + ' namespaces <br/>')
for(i=0;i<matchNamespace.length;i++)
document.write(matchNamespace[i] + '<br/>')
</script>
</head>
<body>
</body>
</html>
js fiddle

For completeness, here's a solution with a YAML parser - provided that it actually is YAML, because the last part (users) isn't valid YAML. Also some indentation wasn't right. I assume it has been modified to not leak sensitive information.
Update: Oh, I see this is a kubernetes config file. So it really is YAML then.
https://jsfiddle.net/1Lpsk740/ (with document.write instead of console.log)
<!DOCTYPE html>
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.js"></script>
<script>
var input = `apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ
server: https://api.someaddress1
name: https://api.anotheraddress
- second_cluster:
certificate-authority-data: LS0tLS1
server: https://api.someaddress2
name: https://api.
contexts:
- context:
cluster: https://api.another1address
namespace: name1
user: user1
name: somename
- another_context:
cluster: https://api.anotheraddress
namespace: esm2
user: admin
name: somename1`;
const doc = jsyaml.load(input);
console.log('servers: ' + doc.clusters.length);
doc.clusters.forEach(e => console.log('- ' + Object.keys(e)[0]));
console.log('namespaces: ' + doc.contexts.length);
doc.contexts.forEach(e => console.log('- ' + Object.keys(e)[0]));
</script>
</html>
Output:
servers: 2
- cluster
- second_cluster
namespaces: 2
- context
- another_context

Related

AWS EKS secrets store provider - Failed to fetch secret from all regions: name

I am using the AWS secrets store CSI provider to sync secrets from the AWS Secret Manager into Kubernetes/EKS.
The SecretProviderClass is:
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: test-provider
spec:
provider: aws
parameters:
objects: |
- objectName: mysecret
objectType: secretsmanager
jmesPath:
- path: APP_ENV
objectAlias: APP_ENV
- path: APP_DEBUG
objectAlias: APP_DEBUG
And the Pod mounting these secrets is:
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
restartPolicy: Never
serviceAccountName: my-account
terminationGracePeriodSeconds: 2
containers:
- name: dotfile-test-container
image: registry.k8s.io/busybox
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/mnt/secret-volume"
volumes:
- name: secret-volume
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: test-provider
The secret exists in the Secret Provider:
{
"APP_ENV": "staging",
"APP_DEBUG": false
}
(this is an example, I am aware I do not need to store these particular variables as secrets)
But when I create the resources, the Pod fails to run with
Warning
FailedMount
96s (x10 over 5m47s)
kubelet
MountVolume.SetUp failed for volume "secret-volume" : rpc error: code = Unknown desc = failed to mount secrets store objects for pod pace/secret-dotfiles-pod,
err: rpc error: code = Unknown desc = Failed to fetch secret from all regions: mysecret
Turns out the error message is very misleading. The problem in my case was due to the type of the APP_DEBUG value. Changing it from a boolean to string
fixed the problem and now the pod starts correctly.
{
"APP_ENV": "staging",
"APP_DEBUG": "false"
}
Seems like a bug in the provider to me.

Envoy filter in istio unable to apply rate limit based on regex

I am working on rate limit using the istio. I want to apply different rate limit based on the regex. The url which has /api/iam/.* should have rate limit of 2 req/minute and default rate limit on other paths should be 100 req/s. I am trying to use
rate_limits:
- actions:
- header_value_match:
descriptor_value: two_legged_path
headers:
- name: ":path"
string_match:
safe_regex:
google_re2: {}
regex: "api/iam/.*"
we used string_match with safe_regex but it is not working. It always applies the default behaviour which is 100 req/s. Could you please help I have followed numerious examples and nothing seemed to work.
The full configuration
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: filter-local-ratelimit-svc
namespace: istio-system
spec:
workloadSelector:
labels:
app: iam-authn-service
env: az-dev
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.local_ratelimit
typed_config:
"#type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
value:
stat_prefix: http_local_rate_limiter
- applyTo: HTTP_ROUTE
match:
context: SIDECAR_INBOUND
routeConfiguration:
vhost:
name: "inbound|http|8080"
route:
action: ANY
patch:
operation: MERGE
value:
route:
rate_limits:
- actions:
- header_value_match:
descriptor_value: two_legged_path
headers:
- name: ":path"
string_match:
safe_regex:
google_re2: {}
regex: "api/iam/.*"
typed_per_filter_config:
envoy.filters.http.local_ratelimit:
"#type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
value:
stat_prefix: http_local_rate_limiter
descriptors:
- entries:
- key: header_match
value: two_legged_path
token_bucket:
max_tokens: 2
tokens_per_fill: 2
fill_interval: 60s
token_bucket:
max_tokens: 100
tokens_per_fill: 100
fill_interval: 1s
filter_enabled:
runtime_key: local_rate_limit_enabled
default_value:
numerator: 100
denominator: HUNDRED
filter_enforced:
runtime_key: local_rate_limit_enforced
default_value:
numerator: 100
denominator: HUNDRED
response_headers_to_add:
- append: false
header:
key: x-local-rate-limit
value: 'true'
The istio doesn't use the latest envoy, the valid doc: https://www.envoyproxy.io/docs/envoy/v1.17.1/api-v3/type/matcher/v3/regex.proto#envoy-v3-api-msg-type-matcher-v3-regexmatcher-googlere2
use safe_regex_match instead of string_match

How to use kubectl patch to add list entry without duplicate?

I have the following Minikube default service account:
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
imagePullSecrets:
- name: gcr-secret
- name: awsecr-cred
- name: dpr-secret
- name: acr-secret
kind: ServiceAccount
metadata:
creationTimestamp: "2022-11-18T20:21:13Z"
name: default
namespace: default
resourceVersion: "10953591"
uid: edcc687f-dbb5-472d-8847-b4dc29096b48
I can add a new imagePullSecrets entry using the following kubectl patch command:
kubectl patch serviceaccount default --type=json -p '[{"op": "add", "path": "/imagePullSecrets/-", "value": {name: artifactory-credentials}}]'
Here's the update default service account:
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
imagePullSecrets:
- name: gcr-secret
- name: awsecr-cred
- name: dpr-secret
- name: acr-secret
- name: artifactory-credentials
kind: ServiceAccount
metadata:
creationTimestamp: "2022-11-18T20:21:13Z"
name: default
namespace: default
resourceVersion: "10956724"
uid: edcc687f-dbb5-472d-8847-b4dc29096b48
However, when I run the kubectl patch command a second time, a duplicate imagePullSecrets entry is added:
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
imagePullSecrets:
- name: gcr-secret
- name: awsecr-cred
- name: dpr-secret
- name: acr-secret
- name: artifactory-credentials
- name: artifactory-credentials
kind: ServiceAccount
metadata:
creationTimestamp: "2022-11-18T20:21:13Z"
name: default
namespace: default
resourceVersion: "10957065"
uid: edcc687f-dbb5-472d-8847-b4dc29096b48
How can I use kubectl patch to add a imagePullSecrets entry only when the entry doesn't already exist? I don't want duplicate imagePullSecrets entries.
I'm using Minikube v1.28.0 and kubectl client version v1.26.1 / server version v1.25.3 on Ubuntu 20.04.5 LTS.
AFAIK unfortunately there is no such filter available the official documentation. But We can do a workaround by using the general syntax like kubectl patch serviceaccount default --type=json -p '{"imagePullSecrets":[{"name": "gcr-secret"},{"name": "artifactory-credentials"},{"name": "acr-secret"}]}'. But we have to update all the imagePullSecrets everytime.
As #Geoff Alexander mentioned the other way is to get the details of resource and validate if the required property is available in the resource, as mentioned in the above comment like $kubectl get serviceaccount -o json or $kubectl get serviceaccount -o yaml.

Mounting AWS Secrets Manager on Kubernetes/Helm chart

I have created an apps cluster deployment on AWS EKS that is deployed using Helm. For proper operation of my app, I need to set env variables, which are secrets stored in AWS Secrets manager. Referencing a tutorial, I set up my values in values.yaml file someway like this
secretsData:
secretName: aws-secrets
providerName: aws
objectName: CodeBuild
Now I have created a secrets provider class as AWS recommends: secret-provider.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: aws-secret-provider-class
spec:
provider: {{ .Values.secretsData.providerName }}
parameters:
objects: |
- objectName: "{{ .Values.secretsData.objectName }}"
objectType: "secretsmanager"
jmesPath:
- path: SP1_DB_HOST
objectAlias: SP1_DB_HOST
- path: SP1_DB_USER
objectAlias: SP1_DB_USER
- path: SP1_DB_PASSWORD
objectAlias: SP1_DB_PASSWORD
- path: SP1_DB_PATH
objectAlias: SP1_DB_PATH
secretObjects:
- secretName: {{ .Values.secretsData.secretName }}
type: Opaque
data:
- objectName: SP1_DB_HOST
key: SP1_DB_HOST
- objectName: SP1_DB_USER
key: SP1_DB_USER
- objectName: SP1_DB_PASSWORD
key: SP1_DB_PASSWORD
- objectName: SP1_DB_PATH
key: SP1_DB_PATH
I mount this secret object in my deployment.yaml, the relevant section of the file looks like this:
volumeMounts:
- name: secrets-store-volume
mountPath: "/mnt/secrets"
readOnly: true
env:
- name: SP1_DB_HOST
valueFrom:
secretKeyRef:
name: {{ .Values.secretsData.secretName }}
key: SP1_DB_HOST
- name: SP1_DB_PORT
valueFrom:
secretKeyRef:
name: {{ .Values.secretsData.secretName }}
key: SP1_DB_PORT
further down in same deployment file, I define secrets-store-volume as :
volumes:
- name: secrets-store-volume
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: aws-secret-provider-class
All drivers are installed into cluster and permissions are set accordingly
with helm install mydeployment helm-folder/ --dry-run I can see all the files and values are populated as expected. Then with helm install mydeployment helm-folder/ I install the deployment into my cluster but with kubectl get all I can see the pod is stuck at Pending with warning Error: 'aws-secrets' not found and eventually gets timeout. In AWS CloudTrail log, I can see that the cluster made request to access the secret and there was no error fetching it. How can I solve this or maybe further debug it? Thank you for your time and efforts.
Error: 'aws-secrets' not found - looks like CSI Driver isn't creating kubernetes secret that you're using to reference values
Since yaml files looks correctly, I would say it's probably CSI Driver configuration Sync as Kubernetes secret - syncSecret.enabled (which is false by default)
So make sure that secrets-store-csi-driver runs with this flag set to true, for example:
helm upgrade --install csi-secrets-store \
--namespace kube-system secrets-store-csi-driver/secrets-store-csi-driver \
--set grpcSupportedProviders="aws" --set syncSecret.enabled="true"

Is it possible to combine AND and OR matches in a Virtual Service definition?

I'm trying to define a Virtual Service in Istio (1.3.3) which has multiple matches but within the matches, there should be OR functionality.
For example : (pseudo code)
match
header-key = value1
OR header-key = value2
OR header-key = value3
OR ....
OR header-key = value100
AND
match
uri-prefix = prefix1
OR uri-prefix = prefix2
OR uri-prefix = prefix3
OR uri-prefix = ...
OR uri-prefix = prefix100
So for every AND block there should be at least one matching OR condition.
I 've tried with a match but then if 1 of all the conditions are met, then it is valid, but what I want is to match one of the API keys and match one of the URI prefixes.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test
namespace: demo
spec:
hosts:
- test1
gateways:
- test-gateway
http:
- match:
- headers:
apikey:
exact: 111
- headers:
apikey:
exact: 222
- headers:
apikey:
exact: 333
- uri:
prefix: /path1/
- uri:
prefix: /path2/
rewrite:
uri: /newpath/v1/
authority: test2
route:
- destination:
host: test2
- fault:
abort:
httpStatus: 444
percent: 100
route:
- destination:
host: test2