tomy_125: Note

tomy_125 の個人的なメモ

Python からAPIで Google Calendar を操作する

目次

進め方

Python Quickstart  |  Google Calendar API  |  Google Developers に沿って行う。

手順

プロジェクトの作成

  • プロジェクトのプルダウンから新規のプロジェクトを作成

  • 新しいプロジェクトから、MyCalendar プロジェクトを作成

Google Calendar API の有効化

  • 左のメニューから 有効なAPIとサービス を選択

  • APIとサービスの有効化

OAuth同意

  • APIを認証するために OAuth認証に同意する
  • Google Workspace を利用していない場合は 外部 のみが選択できる

  • OAuth同意画面 ではアプリ名 に任意の名称を入力し、
    ユーザーサポートメール、デベロッパーの連絡先情報 には自信の Gmail アドレスを入力

  • スコープ では何も入力せず 保存して次へ

  • テストユーザー 自身の Gmailアドレスを追加

  • 概要 で結果を確認

認証情報の作成

  • 認証情報から CREATE CREDENTIALS をクリック

  • OAuthクライアントID を選択

  • アプリケーションの種類に デスクトップアプリ を選択

  • JSONをダウンロード

pipでライブラリをインストール

# pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

サンプルコードの配置

from __future__ import print_function

import datetime
import os.path

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']


def main():
    """Shows basic usage of the Google Calendar API.
    Prints the start and name of the next 10 events on the user's calendar.
    """
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    try:
        service = build('calendar', 'v3', credentials=creds)

        # Call the Calendar API
        now = datetime.datetime.utcnow().isoformat() + 'Z'  # 'Z' indicates UTC time
        print('Getting the upcoming 10 events')
        events_result = service.events().list(calendarId='primary', timeMin=now,
                                              maxResults=10, singleEvents=True,
                                              orderBy='startTime').execute()
        events = events_result.get('items', [])

        if not events:
            print('No upcoming events found.')
            return

        # Prints the start and name of the next 10 events
        for event in events:
            start = event['start'].get('dateTime', event['start'].get('date'))
            print(start, event['summary'])

    except HttpError as error:
        print('An error occurred: %s' % error)


if __name__ == '__main__':
    main()
  • ダウンロードしたJSON をcredentials.json というファイル名で、サンプルコードと同じディレクトリに配置
# ls -l quickstart.py credentials.json 
-rw-r--r-- 1 root root  406 Aug 20 05:06 credentials.json
-rw-r--r-- 1 root root 2611 Aug 20 05:07 quickstart.py

サンプルコードの実行

  • サンプルコードの実行
# python /mnt/quickstart.py
  • 初回実行時は、ブラウザで認証画面が開く(1つ目はVSCodeから実行した場合の確認画面)

  • 続行を選択

  • さらに続行を選択

  • ブラウザに "The authentication flow has completed. You may close this window."と表示される

  • サンプルコードを実行したターミナルに戻ると、結果が取得されている

Getting the upcoming 10 events
2022-08-23 <予定1>
2022-08-26 <予定2>
2022-08-26 <予定3>
2022-09-17 <予定4>
2022-09-18 <予定5>
2022-10-08 <予定6>
2022-10-18 <予定7>
2022-10-22 <予定8>
2022-11-18 <予定9>
2022-12-18 <予定10>
# ls -l quickstart.py credentials.json token.json
-rw-r--r-- 1 root root  406 Aug 20 05:06 credentials.json
-rw-r--r-- 1 root root 2611 Aug 20 05:07 quickstart.py
-rw-r--r-- 1 root root  650 Aug 21 11:24 token.json

参考

pam_fally2 でログイン回数の制限

※こちらのページは断片的な情報のメモです。
※実際は、ここに記載されている設定以外も挙動に影響します。

sshからのログイン失敗回数を制限したい

設定ファイル

  • /etc/pam.d/sshd
    • pam_tally2 を使用してパスワード複数回失敗場合の動作を制御する
auth       required     pam_sepermit.so
auth       substack     password-auth
auth       include      postlogin
auth [success=1 default=ignore] pam_succeed_if.so user in user1
# auth       required     pam_tally2.so deny=5 onerr=fail lock_time=600 serialize
auth       required     pam_tally2.so deny=2 onerr=fail unlock_time=15 serialize

pam_tally2のパラメーター

  • deny=n

    • Deny access if tally for this user exceeds n.
  • lock_time=n

    • Always deny for n seconds after failed attempt.
  • unlock_time=n

    • Allow access after n seconds after failed attempt. If this option is used the user will be locked out for the specified amount of time after he exceeded his maximum allowed attempts. Otherwise the account is locked until the lock is removed by a manual intervention of the system administrator.
  • auth [success=1 default=ignore] pam_succeed_if.so user in user1:user2:user3
    • ログインに何度も失敗してもシステムがユーザーをロックアウトしないようにするには、/etc/pam.d/system-auth と /etc/pam.d/password-authの両方で、pam_faillock が初めて呼び出される行のすぐ上に次の行を追加します。また、user1、user2、よび user3を実際のユーザー名に置き換えてください。

失敗回数の確認・リセット

## 確認
pam_tally2 -u <user>
Login           Failures Latest failure     From
<user>            4    07/25/22 20:28:34  gateway

## リセット
pam_tally2 -u <user> --reset

参考

第4章 ツールとサービスでシステムを強化する Red Hat Enterprise Linux 7 | Red Hat Customer Portal
* 4.1.2. アカウントのロック

pam_tally2(8) - Linux manual page

【SSH】任意の回数ログイン失敗でアカウントをロックする方法 | server-memo.net

Dockerコンテナで systemctl で sshd起動して接続

コンテナ起動

docker run -d --rm -p 127.0.0.1:10022:22 --privileged oraclelinux:7.9 /sbin/init

コンテナに接続

  • コンテナのssh関連設定を実施
docker exec -it <container_name> bash
  • コンテナ内で
useradd newuser
passwd newuser

コンテナにssh接続

  • ホストからコンテナにssh
ssh newuser@localhost -p 10022

以上

yumリポジトリが無い環境に必要なパッケージをダウンロードして持込みたい時のメモ

目次

概要

  • yumリポジトリが無い環境に、必要なパッケージをダウンロードして持ち込もうとした場合、
    依存関係のあるパッケージを調べ、それを全てダウンロードするのは結構大変
  • パッケージ・バージョンまでケアしようとすると、もう少し考えることはあるが、
    おおよそ楽にできる方法を思いついたのでメモ
  • Docker でminimal install の環境を簡単に用意することで、
    yum によるパッケージダウンロード、依存関係の確認、インストールの検証が簡単にできる。

docker image のダウンロードと、コンテナの起動

  • ここでは oracle linux のイメージを利用
  • 7-slim は最低限yum が使えるだけのパッケージが入った、ほぼ minimal install されたイメージ
  • docker を起動する環境の CPU アーキテクチャ は、パッケージ持ち込み先の環境に合わせる  
$ docker pull oraclelinux:7-slim
$ docker run -it --rm -v "$PWD:/mnt" oraclelinux:7-slim

Docker Hub
Differences between oraclelinux:7 and oraclelinux:7-slim For images that want an Oracle Linux 7 user space, Oracle recommends using oraclelinux:7-slim as the base layer as it contains just enough packages for yum to be able to install more packages. The oraclelinux:7 images is based on the package set of what would be installed on a bare-metal server when performing a minimal install of Oracle Linux.

  • OSバージョンの確認
$ cat /etc/os-release

yum リポジトリの確認

  • yum リポジトリの参照先を確認
  • 変更の必要があれば、/etc/yum.repo/ のファイルを編集
# yum repoinfo
Loaded plugins: ovl
ol7_latest                                                                                                                | 3.6 kB  00:00:00     
(1/3): ol7_latest/aarch64/group_gz                                                                                        | 133 kB  00:00:00     
(2/3): ol7_latest/aarch64/updateinfo                                                                                      | 2.2 MB  00:00:00     
(3/3): ol7_latest/aarch64/primary_db                                                                                      |  93 MB  00:00:08     
Repo-id      : ol7_latest/aarch64
Repo-name    : Oracle Linux 7Server Latest (aarch64)
Repo-revision: 1657639913
Repo-updated : Tue Jul 12 15:31:59 2022
Repo-pkgs    : 17228
Repo-size    : 38 G
Repo-baseurl : https://yum.oracle.com/repo/OracleLinux/OL7/latest/aarch64/
Repo-expire  : 21600 second(s) (last: Wed Jul 13 14:36:20 2022)
  Filter     : read-only:present
Repo-excluded: 5290
Repo-filename: /etc/yum.repos.d/oracle-linux-ol7.repo

repolist: 17228

現在のrpm リストを取得

  • ファイルを取得できる様、ホストのディレクトリをマウントした /mntcd しておく
# cd /mnt
# rpm -qa | sort > rpm_list_full_before.txt
# rpm -qa --queryformat "%{name}.%{arch}¥n" | sort > rpm_list_name-arch_before.txt

yum パッケージをダウンロード

  • ここでは java-1.8.0-openjdk と 必要な依存パッケージをダウンロード
# yum install --downloadonly --downloaddir=./ java-1.8.0-openjdk
# ls
acl-2.2.51-15.el7.aarch64.rpm                      libXext-1.3.3-3.el7.aarch64.rpm
alsa-lib-1.1.8-1.el7.aarch64.rpm                   libXfixes-5.0.3-1.el7.aarch64.rpm
....

依存関係のチェック・インストール

# rpm --test -ivh *.rpm
Preparing...                          ################################# [100%]
# rpm -ivh *.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:libjpeg-turbo-1.2.90-8.el7       ################################# [  1%]
   2:libpng-2:1.5.13-8.el7            ################################# [  2%]
   3:freetype-2.8-14.el7_9.1          ################################# [  3%]
   ....
   99:java-1.8.0-openjdk-headless-1:1.8################################# [ 99%]
   100:java-1.8.0-openjdk-1:1.8.0.332.b0################################# [100%]

rpm リストを再度取得

# rpm -qa | sort > rpm_list_full_after.txt
# rpm -qa --queryformat "%{name}.%{arch}¥n" | sort > rpm_list_name-arch_after.txt
  • 追加されたパッケージリストを確認
# grep -x -v -f rpm_list_full_before.txt rpm_list_full_after.txt > rpm_list_add.txt

この後の作業

  • この後は、ダウンロードした rpmrpm リストファイルを目的の環境に持ち込み
  • 持ち込み先の環境で取得した、rpmリストファイルと、持ち込んだリストファイルを比較
  • 必要な rpm ファイルのみをインストール

参考

yum を使用して、パッケージをインストールせずにダウンロードだけ行う - Red Hat Customer Portal

以上

OCI - Compute Instance 起動・停止スクリプトのサンプル

sample

o=${1^^}
ocid="ocid1.instance.oc1.ap-tokyo-1.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"

function get_status(){

        s=`oci compute instance get --instance-id ${ocid}| jq -r '.data."lifecycle-state" '`
        echo $s

}


function start_instance(){
        oci compute instance action --action start --instance-id ${ocid}
}

function stop_instance(){
        oci compute instance action --action stop --instance-id ${ocid}
}

if [ ${o} == "STATUS" ]; then

        get_status

elif [ ${o} == "START"  ]; then

        start_instance

elif [ ${o} == "STOP"  ]; then

        stop_instance

else

        echo "Usage: $0 [STATUS|START|STOP]"

fi

参考

action — OCI CLI Command Reference 3.10.5 documentation

Oracle PL/SQL 中のカーソルの読み取り一貫性

PL/SQL の読取り一貫性を確認

script 1 (cursorでselect)

t2の全行を 1秒おきに1行 fetchすることを、3回ループする

[oracle@db01 20220702]$ cat loop_in_cursor.sql

set line 200 pages 1000 tab off time on timing on serveroutput on
drop table t2 purge;
create table t2 (c1 number(10), c2 varchar2(40));

insert into t2
select level, to_char(sysdate , 'yyyy/mm/dd hh24:mi:ss')
from dual connect by level <= 10;
commit;

declare
        vSQL varchar2(200);
        vC1 number(19);
        vC2 varchar2(40);
        cursor c is
                select
                        c1,
                        c2
                from
                        t2
                ;
begin
        for i in 1..3 loop
                dbms_output.put_line('---- loop ' || to_char(i));
                open c;
                        loop
                                fetch c into vC1, vC2;
                                exit when c%notfound;
                                        dbms_output.put_line(to_char(vC1) || ', ' || vC2);
                                dbms_session.sleep(1);
                        end loop;
                close c;
        end loop;
end;
/

quit;

script 2 (update)

t2 を1行ずつ、1秒間隔で、全行更新するまでループする

[oracle@db01 20220702]$ cat loop_update.sql

set line 200 pages 1000 tab off time on timing on serveroutput on
begin
        for i in 1..20 loop

                update t2 set c2 = to_char(sysdate,'yyyy/mm/dd hh24:mi:ss') where c1 = i;
                commit;
                dbms_session.sleep(1);

        end loop;
end;
/

結果

script 実行中に、script 2を実行する。 script 1 のloop 1回目は、最初に投入したデータを表示 script 1 のloop 2回目は、script 2 が t2 を途中まで更新したデータを表示 script 1 のloop 3回目は、script 2 が t2 を最後まで表示したデータを表示

→ カーソルがオープンしたタイミングのデータが表示される

  • script 1 結果
[oracle@db01 20220702]$ sqlplus inserter/oracle@pdb1 @loop_in_cursor.sql

SQL*Plus: Release 19.0.0.0.0 - Production on Sat Jul 2 06:21:12 2022
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

Last Successful login time: Sat Jul 02 2022 06:20:11 +00:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0


Table dropped.

Elapsed: 00:00:00.01

Table created.

Elapsed: 00:00:00.01

10 rows created.

Elapsed: 00:00:00.00

Commit complete.

Elapsed: 00:00:00.00
---- loop 1
1, 2022/07/02 06:21:12
2, 2022/07/02 06:21:12
3, 2022/07/02 06:21:12
4, 2022/07/02 06:21:12
5, 2022/07/02 06:21:12
6, 2022/07/02 06:21:12
7, 2022/07/02 06:21:12
8, 2022/07/02 06:21:12
9, 2022/07/02 06:21:12
10, 2022/07/02 06:21:12
---- loop 2
1, 2022/07/02 06:21:16
2, 2022/07/02 06:21:17
3, 2022/07/02 06:21:18
4, 2022/07/02 06:21:19
5, 2022/07/02 06:21:20
6, 2022/07/02 06:21:21
7, 2022/07/02 06:21:22
8, 2022/07/02 06:21:12
9, 2022/07/02 06:21:12
10, 2022/07/02 06:21:12
---- loop 3
1, 2022/07/02 06:21:16
2, 2022/07/02 06:21:17
3, 2022/07/02 06:21:18
4, 2022/07/02 06:21:19
5, 2022/07/02 06:21:20
6, 2022/07/02 06:21:21
7, 2022/07/02 06:21:22
8, 2022/07/02 06:21:23
9, 2022/07/02 06:21:24
10, 2022/07/02 06:21:25

PL/SQL procedure successfully completed.

Elapsed: 00:00:30.74
Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
[oracle@db01 20220702]$
  • script 2 結果
[oracle@db01 20220702]$ sqlplus inserter/oracle@pdb1 @loop_update.sql

SQL*Plus: Release 19.0.0.0.0 - Production on Sat Jul 2 06:21:16 2022
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

Last Successful login time: Sat Jul 02 2022 06:21:12 +00:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0


PL/SQL procedure successfully completed.

Elapsed: 00:00:20.48
06:21:36 SQL>

PL/SQL のエラーハンドリング

エラー発生方法

PL/SQL 実行中に、参照する表を更新することで ORA-1555 を発生させエラーとする

ORA-1555 の再現ケース - tomy_125: Note

EXCEPTION なし

15:18:15 SQL> set serveroutput on
15:21:15 SQL> declare
15:21:15   2    vC1 number(10);
15:21:15   3    vC2 varchar(500);
15:21:15   4  begin
15:21:15   5      select
15:21:15   6        /*+ LEADING(a b) USE_NL(b) */
15:21:15   7        a.c1, a.c2
15:21:15   8        into vC1, vC2
15:21:15   9      from t1 a, t1 b
15:21:15  10      order by a.c1, b.c1
15:21:15  11      ;
15:21:15  12  end;
15:21:15  13  /
declare
*
ERROR at line 1:
ORA-01555: snapshot too old: rollback segment number 9 with name
"_SYSSMU9_3581032004$" too small
ORA-06512: at line 5


Elapsed: 00:00:09.24
15:21:26 SQL>

EXCEPTION あり、OTHER でハンドリング

15:21:26 SQL> set serveroutput on
15:22:09 SQL> declare
15:22:09   2    vC1 number(10);
15:22:09   3    vC2 varchar(500);
15:22:09   4  begin
15:22:09   5      select
15:22:09   6        /*+ LEADING(a b) USE_NL(b) */
15:22:09   7        a.c1, a.c2
15:22:09   8        into vC1, vC2
15:22:09   9      from t1 a, t1 b
15:22:09  10      order by a.c1, b.c1
15:22:09  11      ;
15:22:09  12  exception
15:22:09  13      when others then
15:22:09  14          dbms_output.put_line('-- other error received.');
15:22:09  15  end;
15:22:09  16  /
-- other error received.

PL/SQL procedure successfully completed.

Elapsed: 00:00:09.67
15:22:19 SQL>

EXCEPTION あり、ユーザー定義例外

15:23:00 SQL> set serveroutput on
15:23:01 SQL> declare
15:23:01   2    vC1 number(10);
15:23:01   3    vC2 varchar(500);
15:23:01   4    snapshot_too_old exception;
15:23:01   5    pragma exception_init(snapshot_too_old, -1555);
15:23:01   6  begin
15:23:01   7      select
15:23:01   8        /*+ LEADING(a b) USE_NL(b) */
15:23:01   9        a.c1, a.c2
15:23:01  10        into vC1, vC2
15:23:01  11      from t1 a, t1 b
15:23:01  12      order by a.c1, b.c1
15:23:01  13      ;
15:23:01  14  exception
15:23:01  15      when snapshot_too_old then
15:23:01  16          dbms_output.put_line('-- ORA-1555 received.');
15:23:01  17      when others then
15:23:01  18          dbms_output.put_line('-- other error received.');
15:23:01  19  end;
15:23:01  20  /
-- ORA-1555 received.

PL/SQL procedure successfully completed.

Elapsed: 00:00:11.77
15:23:13 SQL>