【React.js】makeStylesのスタイル指定方法
React.js(Next.js)で実装する際にmakeStyles
の利用方法を調べたので、忘れないようにメモ。
気になるものがあったら、順次追記していきます。
first-child
特に迷うことは無い。
const useStyles = makeStyles({ root: { '& div:first-child': { .... }, });
last-child
first-child
と同様。
const useStyles = makeStyles({ root: { '& div:last-child': { .... }, });
nth-child
スタイルを指定したい要素の中に&:nth-child(n)
という形式で定義する。
const useStyles = makeStyles({ root: { '&:nth-child(2)': { .... }, });
not
&:not(:~)
という形で指定可能。
const useStyles = makeStyles({ root: { '&:not(:nth-child(2))': { .... }, });
メディアクエリ
@media (min-width:1280px)
のような形で指定可能。
const useStyles = makeStyles({ root: { display: 'flex', '@media (max-width:1024px)': { display: 'block', .... }, });
【HiveQL】pyhiveとPrestoでテーブル操作
beeline
で実行していたクエリをpyhive
+ Presto
で再実装した際に書き方が違う部分があった為、備忘メモ。
LOCATIONを指定してテーブル作成
元のクエリはこちら。
CREATE EXTERNAL TABLE <テーブル名> (<カラム名> <型>, ...) ROW FORMAT DELIMITED FIELDS TERMINATED BY <区切文字、eg. '\t'> LOCATION <HDFSのパス>
pyhive
+ Presto
で書くと以下のようになる。
cursor = presto.connect(...).cursor() query = "CREATE TABLE test_table (id integer, note varchar) WITH (format='TEXTFILE', textfile_field_separator='\t', external_location='/path/to/hdfs')" cursor.execute(query) # fetchしないとテーブル作成後の処理が上手くいかない、エラーログも見れる print(cursor.fetchone()) cursor.execute('desc test_table') print(cursor.fetchone())
INSERT OVERWRITE
元のクエリ。
INSERT OVERWRITE <テーブル名> SELECT sum_a, b FROM ( SELECT SUM(a) AS sum_a, b FROM ( SELECT a, b FROM table1 UNION ALL SELECT a, b FROM table2 UNION ALL SELECT a, b FROM table3 ) t1 GROUP BY b ) t2 WHERE sum_a > {hivevar:a_param}
Presto
でINSERT OVERWRITE
は使用できません。
drop後にINSERT INTO
で作成する必要があります。
cursor = presto.connect(...).cursor() # drop cursor.execute('DROP TABLE IF EXISTS test_table') query = 'INSERT INTO test_table (sum_a, b) WITH tmp_tb AS ( SELECT SUM(a) AS sum_a, b FROM ( SELECT a, b FROM table1 UNION ALL SELECT a, b FROM table2 UNION ALL SELECT a, b FROM table3 ) GROUP BY b) SELECT sum_a, b FROM tmp_tb WHERE sum_a > %s' cursor.execute(query, (100,)) print(cursor.fetchall())
【Node.js】npmパッケージの脆弱性対応
CIで脆弱性チェックがエラーとなり、npm audit
以外の方法で応急処置をしたのでメモ。
修正後は要動作確認。
npm audit
まずは npm audit
等で検出されたパッケージのレポジトリを調べ、必要であれば package.json のバージョンを修正後にnpm audit fix
を実行。
node_modules や package-lock.jsonは削除した方が間違いが無さそう。
$ npm audit fix
npm-force-resolutions
npm audit fix
で解決しなかった場合に、どうにかして脆弱性のあるライブラリのバージョンを修正したい場合にnpm-force-resolutions
が使用できます。
package.jsonのscripts.preinstallにnpx npm-force-resolutions
、resolutions
にバージョンを修正したいパッケージ情報を記載します。
依存関係を無理やり変更させる為、使用する場合はバージョンアップ後の動作確認を良く行ってください。
{ "name": "xxxxx", "version": "0.0.1", "description": "", "scripts": { "preinstall": "npx npm-force-resolutions", # ここ "build": "..." }, "dependencies": { "vue": "^2.6.14", ... }, "dev-dependencies": { "vue-jest": "^4.0.1", ... }, "resolutions": { "ansi-regex": "5.0.1" # ここ } }
Dockerfileからbuildする際にエラーとなった為、.npmrcにunsafe-perm=true
を追記して解決しました。
unsafe-perm=true
で、パッケージスクリプト(preinstall)の実行時のUID/GID切り替えを抑制します。
# .npmrc registry=https://xxx.xxx.xxx/... unsafe-perm=true # ここ
【Python】urllibでプロキシ設定
urllib
で社内のプロキシサーバーを経由して外部接続という処理を実装しました。
外部接続先のAPIでBasic認証が必要で、少し詰まったのでメモ。
requests
モジュールだと、プロキシ設定 + 接続先でBasic認証が上手く動かなかった為、urllib
モジュールを使用しています。
上手いやり方などあれば、教えてください😊
実装
import os import base64 import json import urllib.request def exec_proxy_request(usename: str, passwd: str, token: str): user_pass = f'{usename}:{passwd}' header = { # アクセス先のBasic認証 'Authorization': f"Basic {base64.b64encode(user_pass.encode('utf-8')).decode('utf-8')}" # プロキシサーバの認証情報、必要に応じて 'Proxy-Authorization': f'Bearer {token}' } req = urllib.request.Request('<アクセス先URL>', headers=header, method='GET') # プロキシの設定 req.set_proxy('xxx.proxy.jp', 'http') req.set_proxy('xxx.proxy.jp', 'https') with urllib.request.urlopen(req) as res: status_code = res.getcode() res_body = res.read().decode('utf-8') if not status_code == 200: raise Exception(res_body) json_data = json.loads(res_body) return json_data
【Kubernetes】IngressのURL Rewrite設定
Ingressのpath設定でリクエストを振り分ける際にURLのrewriteを行ったのでメモ。
設定がコントローラーにより異なるようです。
kubernetes-ingress
annotations
にnginx.ingress.kubernetes.io/rewrite-target
を設定すると良いようです。
rewrite-targetに/
を指定する事により、/v2
アクセス時にservice2
の/
(インデックスルート)にアクセスします。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test namespace: test-namespace annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - http: paths: - path: /v2 pathType: Prefix backend: service: name: service2 port: number: 80 - path: / pathType: Prefix backend: service: name: service1 port: number: 80
- Git Hub
Nginx Ingress Controller
kubernetes-ingress
と同様にnginx.ingress.kubernetes.io/rewrite-target
で指定できるようです。
- Git Hub
nghttpx Ingress Controller
zlab社製のnghttpx
はingress.zlab.co.jp/path-config
にpathのrewrite処理を記載する必要があります。
詳細はドキュメントが参考になります。
以下の設定では、example.co.jp/v2/
アクセス時にservice2
の/
にルーティングされます。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test namespace: test-namespace annotations: ingress.zlab.co.jp/path-config: | example.co.jp/v2/: mruby: | class App def on_req(env) # `/v2`を削除している env.req.path = env.req.path.sub(/^\/[^\/]+/, '') end end App.new spec: rules: - http: paths: # `/v2`も入れないと`example.co.jp/v2`(最後の`/`無し)がNot Foundとなります - path: /v2 pathType: Prefix backend: service: name: service2 port: number: 80 - path: /v2/ pathType: Prefix backend: service: name: service2 port: number: 80 - path: / pathType: Prefix backend: service: name: service1 port: number: 80
- Git Hub
Traefik Controller (Rancher, k3s)
k3s
環境ではIngressControllerにTraefie
がデフォルトで適用されます。
今までのIngressControllerと異なり、MIddleware
というCRDのデプロイが別途必要になります。
以下、/v2
アクセス時にservice2
の/
(インデックスルート)にアクセスする例となります。
apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: replacepathregex-service2 namespace: test-namespace spec: replacePathRegex: regex: ^/v2/(.*) replacement: /$1
annotations
にtraefik.ingress.kubernetes.io/router.middlewares
を指定します。
設定する値は${namespace名}-${Middleware名}@kubernetescrd
という形式にする必要があります。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test namespace: test-namespace annotations: traefik.ingress.kubernetes.io/router.middlewares: test-namespace-replacepathregex-service2@kubernetescrd spec: ingressClassName: traefik rules: - http: paths: - path: /v2 pathType: Prefix backend: service: name: service2 port: number: 80 - path: / pathType: Prefix backend: service: name: service1 port: number: 80
【Python】smtplibでメール送信
Pythonでメール通知の実装メモ。
ホスト名などは適宜変更してください。
実装
ライブラリは不要です。
# -*- coding: utf-8 -*- import getpass import platform import smtplib from datetime import datetime from email.mime.text import MIMEText from email.utils import formatdate def send_mail(to: str, mail_text: str): """ メール送信 :param to: 送信先 :param mail_text: 本文 """ now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') host_name = platform.uname()[1] message = MIMEText(mail_text) message['Subject'] = f'[{now}][{host_name}]' message['From'] = f'{getpass.getuser()}@{host_name}' message['To'] = to message['Date'] = formatdate() with smtplib.SMTP('localhost') as smtp: smtp.send_message(message)
【Kubernetes】kubectl の便利コマンド
使わなくなると忘れそうなので、kubectlコマンドをメモ。
alias k=kubectl
実行済の想定です。
随時、追加します。
入門ならこの一冊😊
トークン取得
$ (k describe secret $(k get secrets | grep <サービスアカウント名> | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d '\t')
ネームスペース切り替え
$ k config set-context $(k config current-context) --namespace=<ネームスペース> # namespace一覧 $ k config view | grep namespace
tls用secret作成
base64デコード時のオプションを--decode
とすると、macでも動きます。
$ k create secret tls <secret名> --key=xxx.key --cert=xxx.crt # 確認コマンド $ k get secret/<secret名> -o yaml # jqが使える場合、項目指定も $ k get secret/<secret名> -o json | jq -r '.data."<項目名>" | base64 --decode' # historyに出力させたくない場合 $ k get secret/<secret名> -o yaml > secret.yaml $ grep "^data:" -A <secretの件数> secret.yaml | awk -F '{print $2}' | base64 --decode
リソースを更新して再起動
# コンフィグマップの編集 $ k edit cm <ConfigMap名> # 変更を反映させる為、再起動 $ k rollout restart <deployment名>
ポートフォワードでデバッグ
以下のコマンドで対象Podの80番ポートがlocalhost:8080
でアクセス可能となる。
$ k port-forward <pod名> 8080:80