Google DeepMindが2018年に開発した、アミノ酸の配列情報からタンパク質の立体構造を予測するAI「AlphaFold」は、多くの重要な分野での研究を加速させることを目的に、2021年にオープンソース化されました。2024年5月にはより多くの生命分子の構造と相互作用を予測できるAIモデル「AlphaFold 3」をリリースし、当初は完全なモデルを公開していませんでしたが、前モデルに続いてAlphaFold 3もオープンソース化しました。
Google DeepMindがAIですべての生命分子の構造と相互作用を予測できる「AlphaFold 3」をオープンソース化、科学的発見と創薬の加速へ - GIGAZINE
⇧ どちらが正しいのか分かりませんが、
- すべての生命分子の構造
- 多くの生命分子の構造
では天と地ほど意味が変わってくる気がするんですけどね...
OxidizedをDockerで動作検証する際はmodelクラスで現在日時を出力するコマンドを追加するが吉
何度か本ブログでも話に出ている、
Oxidized is a network device configuration backup tool. It's a RANCID replacement!
It is light and extensible and supports over 130 operating system types.
⇧「Oxidized」という「Ruby」のライブラリでまたもや泥沼にハマったので備忘録として。
「Oxidized」側で「modelクラス」のテンプレートが用意されているのですが、
■標準的なLinux ディストリビューションで利用可能なmodelクラス
■https://github.com/ytti/oxidized/blob/master/lib/oxidized/model/linuxgeneric.rb
class LinuxGeneric < Oxidized::Model using Refinements prompt /^(\w.*|\W.*)[:#$] / comment '# ' # add a comment in the final conf def add_comment(comment) "\n###### #{comment} ######\n" end cmd :all do |cfg| cfg.gsub! /^(default (\S+).* (expires) ).*/, '\\1 <redacted>' cfg.cut_both end # show the persistent configuration pre do cfg = add_comment 'THE HOSTNAME' cfg += cmd 'cat /etc/hostname' cfg += add_comment 'THE HOSTS' cfg += cmd 'cat /etc/hosts' cfg += add_comment 'THE INTERFACES' cfg += cmd 'ip link' cfg += add_comment 'RESOLV.CONF' cfg += cmd 'cat /etc/resolv.conf' cfg += add_comment 'IP Routes' cfg += cmd 'ip route' cfg += add_comment 'IPv6 Routes' cfg += cmd 'ip -6 route' cfg += add_comment 'MOTD' cfg += cmd 'cat /etc/motd' cfg += add_comment 'PASSWD' cfg += cmd 'cat /etc/passwd' cfg += add_comment 'GROUP' cfg += cmd 'cat /etc/group' cfg += add_comment 'nsswitch.conf' cfg += cmd 'cat /etc/nsswitch.conf' cfg += add_comment 'VERSION' cfg += cmd 'cat /etc/issue' cfg end cfg :telnet do username /^Username:/ password /^Password:/ end cfg :telnet, :ssh do post_login do if vars(:enable) == true cmd "sudo su -", /^\[sudo\] password/ cmd @node.auth[:password] elsif vars(:enable) cmd "su -", /^Password:/ cmd vars(:enable) end end pre_logout do cmd "exit" if vars(:enable) end pre_logout 'exit' end end
■https://github.com/ytti/oxidized/blob/master/lib/oxidized/model/ios.rb
class IOS < Oxidized::Model using Refinements prompt /^([\w.@()-]+[#>]\s?)$/ comment '! ' # example how to handle pager # expect /^\s--More--\s+.*$/ do |data, re| # send ' ' # data.sub re, '' # end # non-preferred way to handle additional PW prompt # expect /^[\w.]+>$/ do |data| # send "enable\n" # send vars(:enable) + "\n" # data # end cmd :all do |cfg| # cfg.gsub! /\cH+\s{8}/, '' # example how to handle pager # cfg.gsub! /\cH+/, '' # example how to handle pager # get rid of errors for commands that don't work on some devices cfg.gsub! /^% Invalid input detected at '\^' marker\.$|^\s+\^$/, '' cfg.cut_both end cmd :secret do |cfg| cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>' cfg.gsub! /^(snmp-server host \S+( vrf \S+)?( informs?)?( version (1|2c))?) +\S+( .*)?$*/, '\\1 <secret hidden>\\6' cfg.gsub! /^(username .+ (password|secret) \d) .+/, '\\1 <secret hidden>' cfg.gsub! /^(enable (password|secret)( level \d+)? \d) .+/, '\\1 <secret hidden>' cfg.gsub! /^( +(?:password|secret)) (?:\d )?\S+/, '\\1 <secret hidden>' cfg.gsub! /^(.*wpa-psk ascii \d) (\S+)/, '\\1 <secret hidden>' cfg.gsub! /^(.*key 7) (\d.+)/, '\\1 <secret hidden>' cfg.gsub! /^(tacacs-server (.+ )?key) .+/, '\\1 <secret hidden>' cfg.gsub! /^(crypto isakmp key) (\S+) (.*)/, '\\1 <secret hidden> \\3' cfg.gsub! /^( +ip ospf message-digest-key \d+ md5) .+/, '\\1 <secret hidden>' cfg.gsub! /^( +ip ospf authentication-key) .+/, '\\1 <secret hidden>' cfg.gsub! /^( +neighbor \S+ password) .+/, '\\1 <secret hidden>' cfg.gsub! /^( +vrrp \d+ authentication text) .+/, '\\1 <secret hidden>' cfg.gsub! /^( +standby \d+ authentication) .{1,8}$/, '\\1 <secret hidden>' cfg.gsub! /^( +standby \d+ authentication md5 key-string) .+?( timeout \d+)?$/, '\\1 <secret hidden> \\2' cfg.gsub! /^( +key-string) .+/, '\\1 <secret hidden>' cfg.gsub! /^((tacacs|radius) server [^\n]+\n( +[^\n]+\n)* +key) [^\n]+$/m, '\1 <secret hidden>' cfg.gsub! /^( +ppp (chap|pap) password \d) .+/, '\\1 <secret hidden>' cfg.gsub! /^( +security wpa psk set-key (?:ascii|hex) \d) (.*)$/, '\\1 <secret hidden>' cfg.gsub! /^( +dot1x username \S+ password \d) (.*)$/, '\\1 <secret hidden>' cfg.gsub! /^( +mgmtuser username \S+ password \d) (.*) (secret \d) (.*)$/, '\\1 <secret hidden> \\3 <secret hidden>' cfg.gsub! /^( +client \S+ server-key \d) (.*)$/, '\\1 <secret hidden>' cfg end cmd 'show version' do |cfg| comments = [] comments << cfg.lines.first lines = cfg.lines lines.each_with_index do |line, i| slave = '' slaveslot = '' if line =~ /^Slave in slot (\d+) is running/ slave = " Slave:" slaveslot = ", slot #{Regexp.last_match(1)}" end comments << "Image:#{slave} Compiled: #{Regexp.last_match(1)}" if line =~ /^Compiled (.*)$/ comments << "Image:#{slave} Software: #{Regexp.last_match(1)}, #{Regexp.last_match(2)}" if line =~ /^(?:Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/ comments << "ROM Bootstrap: #{Regexp.last_match(3)}" if line =~ /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/ comments << "BOOTFLASH: #{Regexp.last_match(1)}" if line =~ /^BOOTFLASH: .*(Version.*)$/ comments << "Memory: nvram #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (non-volatile|NVRAM)/ comments << "Memory: flash #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (flash memory|flash internal|processor board System flash|ATA CompactFlash)/i comments << "Memory: pcmcia #{Regexp.last_match(2)} #{Regexp.last_match(3)}#{Regexp.last_match(4)} #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i if line =~ /(\S+(?:\sseries)?)\s+(?:\(([\S ]+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i sproc = Regexp.last_match(1) cpu = Regexp.last_match(2) mem = Regexp.last_match(3) cpuxtra = '' comments << "Chassis type:#{slave} #{sproc}" comments << "Memory:#{slave} main #{mem}" # check the next two lines for more CPU info comments << "Processor ID: #{Regexp.last_match(1)}" if cfg.lines[i + 1] =~ /processor board id (\S+)/i if cfg.lines[i + 2] =~ /(cpu at |processor: |#{cpu} processor,)/i # change implementation to impl and prepend comma cpuxtra = cfg.lines[i + 2].gsub("implementation", 'impl').gsub(/^/, ', ').chomp end comments << "CPU:#{slave} #{cpu}#{cpuxtra}#{slaveslot}" end comments << "Image: #{Regexp.last_match(1)}" if line =~ /^System image file is "([^"]*)"$/ end comments << "\n" comment comments.join "\n" end cmd 'show vtp status' do |cfg| cfg.gsub! /^$\n/, '' cfg.gsub! /Configuration last modified by.*\n/, '' cfg.gsub! /^/, 'VTP: ' unless cfg.empty? comment "#{cfg}\n" end cmd 'show inventory' do |cfg| comment cfg end post do cmd_line = 'show running-config' cmd_line += ' view full' if vars(:ios_rbac) cmd cmd_line do |cfg| cfg = cfg.each_line.to_a[3..-1] cfg = cfg.reject { |line| line.match /^ntp clock-period / }.join cfg = cfg.each_line.reject { |line| line.match /^! (Last|No) configuration change (at|since).*/ unless line =~ /\d+\sby\s\S+$/ }.join cfg.gsub! /^Current configuration : [^\n]*\n/, '' cfg.gsub! /^ tunnel mpls traffic-eng bandwidth[^\n]*\n*( (?: [^\n]*\n*)* tunnel mpls traffic-eng auto-bw)/mx, '\1' cfg end end cfg :telnet do username /^Username:/i password /^Password:/i end cfg :telnet, :ssh do # preferred way to handle additional passwords post_login do if vars(:enable) == true cmd "enable" elsif vars(:enable) cmd "enable", /^[pP]assword:/ cmd vars(:enable) end end post_login 'terminal length 0' post_login 'terminal width 0' pre_logout 'exit' end end
⇧ どういうわけか、取得した日時を出力するコマンドが実装されていないというね...
『Oxidized is a network device configuration backup tool.』というぐらいだから、当然、処理された日時は出力してくれてるものだと思い込んでいたのが良くなかったのだが、これに気付かず貴重な時間を浪費してしまいましたと...
残念ながら、「Oxidized」側で用意されている「modelクラス」を検証する場合は、対象機器の方で設定を変えたりする必要があることになるのだけど、今回は、「modelクラス」を追加する話であったので、表題の件に落ち着きましたと。
まぁ、普通、バックアップするとなったら、バックアップした日時を出力するものだと思うのだけど、そうしない世界線もあるということが教訓というわけで、バイアスを排除するのは難しいということですかね。
出力について、
⇧「git」以外であれば気にしなくても良い問題だったのかもしれないですが...
今回は、「Cisco IOS」の「modelクラス」をカスタマイズする話であったので、
⇧「show clock」というコマンドを追加した「modelクラス」を用意し、出力されるようにして解決した。
これで、docker-compose up、downを繰り返しても、出力に差分が生まれることになるので(現在日時を出力するようにしたので、ミリ秒の差分を扱えるはず)、「Oxidized」内部で利用されている「Rugged」というライブラリの処理で、Gitのローカルの「bare repository」にgit commitされるようになる。
何と言うか、対象機器の設定が変更されない限り、初回のバックアップを取得後は、永久にバックアップされないということになるんかね?
それは、最早、バックアップしてることにはならないのでは?と思うなどした。
「Oxidized」の意図していることが分からんので、何とも言えんけど...
毎度モヤモヤ感が半端ない…
今回はこのへんで。